确定:在线段上的点 [英] determinate: is point on line segment

查看:127
本文介绍了确定:在线段上的点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写Java方法,如果point(x,y)位于线段上,则返回boolean真,否则返回false.

I am trying to code an java methods wich returns an boolean true if a point(x,y) is on a line segment and false if not.

我尝试过:

public static boolean OnDistance(MyLocation a, MyLocation b, MyLocation queryPoint) {

    double value = java.lang.Math.signum((a.mLongitude - b.mLongitude) * (queryPoint.mLatitude - a.mLatitude)
            - (b.mLatitude - a.mLatitude) * (queryPoint.mLongitude - a.mLongitude));
    double compare = 1;
    if (value == compare) {
        return true;
    }

    return false;
}

但是它不起作用. 帮助和建议,不胜感激.谢谢!

but it doesnt work. help and advice is greatly appreciated. Thank you!

推荐答案

我不是 JAVA 编码器,所以我坚持数学运算...对于初学者,请假设您在飞机上(而不是球面) )

I am not JAVA coder so I stick to math behind ... For starters let assume you are on plane (not sphere surface)

  1. 我会使用向量数学,所以让:


a,b-是行端点
q-查询点
c=q-a-查询的行方向向量
d=b-a-线方向矢量


a,b - be the line endpoints
q - queried point
c=q-a - queried line direction vector
d=b-a - line direction vector

使用点积进行参数提取

t=dot(c,d)/(|c|*|d|)


t是行参数<0,1>,如果超出范围q不在行内
|c|=sqrt(c.x*c.x+c.y*c.y)向量的大小
dot(c,d)=c.x*d.x+c.y*d.y标量向量相乘


t is line parameter <0,1> if out of range q is not inside line
|c|=sqrt(c.x*c.x+c.y*c.y) size of vector
dot(c,d)=c.x*d.x+c.y*d.y scalar vector multiply

现在计算线上的对应点

e=a+(t*d)


eab

计算qab

compute perpendicular distance of q and ab

l=|q-e|;

如果(l>treshold),则q不在行ab上,否则在ab行上.阈值是您仍在接受为线内线的最大距离.不需要l sqrt-ed阈值常数可以用2来代替速度.

if (l>treshold) then q is not on line ab else it is on the line ab. The threshold is the max distance from line you are still accepting as inside line. No need to have l sqrt-ed the threshold constant can be powered by 2 instead for speed.

如果将所有这些都添加到单个方程式中

然后某些事情会自我简化(希望不会犯一些愚蠢的数学错误)

then some things will simplify itself (hope did not make some silly math mistake)

l=|(q-a)-(b-a)*(dot(q-a,b-a)/|b-a|^2)|;
return (l<=treshold);

l=|c-(d*dot(c,d)/|d|^2)|;
return (l<=treshold);

如您所见,我们甚至不需要sqrt:)

As you can see we do not even need sqrt for this :)

[注释]

如果需要球形或椭圆形表面,则需要指定更近的半轴.这条线变为弧线/曲线,需要进行一些校正,具体取决于表面的形状.

If you need spherical or ellipsoidal surface instead then you need to specify it closer which it is what are the semi axises. The line become arc/curve and need some corrections which depends on the shape of surface see

,但也可以通过近似来完成,也可以通过对点e的二进制搜索来实现,请参见:

but can be done also by approximation and may be also by binary search of point e see:

使用的矢量数学可以在最后找到:

The vector math used can be found here at the end:

此处3D C ++实现(具有不同的名称):

double distance_point_axis(double *p,double *p0,double *dp)
    {
    int i;
    double l,d,q[3];
    for (i=0;i<3;i++) q[i]=p[i]-p0[i];                  // q = p-p0
    for (l=0.0,i=0;i<3;i++) l+=dp[i]*dp[i];             // l = |dp|^2
    for (d=0.0,i=0;i<3;i++) d+=q[i]*dp[i];              // d = dot(q,dp)
    if (l<1e-10) d=0.0; else d/=l;                      // d = dot(q,dp)/|dp|^2
    for (i=0;i<3;i++) q[i]-=dp[i]*d;                    // q=q-dp*dot(q,dp)/|dp|^2
    for (l=0.0,i=0;i<3;i++) l+=q[i]*q[i]; l=sqrt(l);    // l = |q|
    return l;
    }

其中p0[3]是轴上的任何点,而dp[3]是轴的方向向量. p[3]是您想要到轴的距离的查询点.

Where p0[3] is any point on axis and dp[3] is direction vector of axis. The p[3] is the queried point you want the distance to axis for.

这篇关于确定:在线段上的点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆