确定:是线上段

时间:2015-09-24 12:18:08

标签: line point segment

我正在尝试编写一个java方法,如果一个点(x,y)在一个线段上,则返回一个布尔值true,否则返回false。

我试过了:

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;
}

但它不起作用。 非常感谢帮助和建议。谢谢!

1 个答案:

答案 0 :(得分:2)

我不是JAVA编码器所以我坚持数学背后......对于初学者来说假设你在飞机上(不是球面)

  1. 我会使用Vector数学,所以让我们:

    • a,b - 是行终点
    • q - 查询点
    • c=q-a - 查询行方向向量
    • d=b-a - 行方向向量
  2. 使用点积进行参数提取

    • 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标量矢量mutiply
  3. 现在计算在线的对应点

    • e=a+(t*d)
    • eq
    • ab的最近点
  4. 计算qab的垂直距离

    • l=|q-e|;
    • 如果(l>treshold),则q不在行ab,否则就行ab
    • treshold是您仍然接受为内线的最大距离
    • 无需l sqrt-ed阈值常数可由2而不是速度提供
  5. 如果将所有这些添加到单个等式中

    • 然后有些事情会简化自己(希望没有做出一些愚蠢的数学错误)
    • l=|q-a-(dot(q-a,b-a)/|q-a|)|;
    • l=|c-(dot(c,d)/|c|)|;
    • return (l<=treshold)
  6. <强> [注释]

    • 如果您需要球形或椭圆形表面,那么您需要将它指定得更近,它是什么是半轴...
    • 线条变为弧形/曲线,需要一些取决于表面形状的修正
    • 请参阅Projecting a point onto a path
    • 但也可以通过近似来完成,也可以通过点e
    • 的二进制搜索来完成
    • 请参阅mine approx class in C++