在Java Swing中检查点是否在直线上

3

我已经画了一条线和一个点,现在想要检查这个点是否在这条线上。我已经将线的坐标保存在数组中(因为有多条线),我想要检查当前点是否在最后一条线上。

if (positionX1 == positionX2 && positionY1 == positionY2) {
    float m = line.getSlope(
        drawLines[currentLines - 1][2], drawLines[currentLines - 1][3],
        drawLines[currentLines - 1][0], drawLines[currentLines - 1][1]);
    m = Float.parseFloat(df.format(m));
    float c = line.getIntercept(
        drawLines[currentLines - 1][2], drawLines[currentLines - 1][3],
        drawLines[currentLines - 1][0], drawLines[currentLines - 1][1]);
    c = Math.round(c);
    m1 = line.getSlope(positionX2, positionY2,
        drawLines[currentLines - 1][0], drawLines[currentLines - 1][1]);
    m1 = Float.parseFloat(df.format(m1));
    System.out.println(m + "   " + m1);
    c1 = line.getIntercept(positionX2, positionY2,
        drawLines[currentLines - 1][0], drawLines[currentLines - 1][1]);
    c1 = Math.round(c1);

    if (m == m1 && ((c == c1) || (c == c1 - 1) || (c == c1 + 1))) {
        System.out.println("Point is on Line");
    }
}

问题在于当一个点靠近线的起始点或一条线接近垂直于斜率m1和截距c1的值时,m1和c1的变化巨大。因此,检测一个点是否在直线上存在问题。如何检查这种情况?


不是针对你的问题,但你考虑过使用Java的Point类吗?这可能有助于使你的代码更易于理解。 - Tom Elliott
关于c1和m1在直线趋近垂直时发生巨大变化,这是因为斜率趋近无限大,截距变得毫无意义,因此讨论这些值就不再有意义。 - thatidiotguy
在数学术语上:如果 ((x-x1)/(x2-x1)=(y-y1)/(y2-y1)),其中p(x,y)是要测试的点,而(x1,y1),(x2,y2) 是线条的边缘(或线条的任意两个点),那么p在该线条上(或类似这样的情况...)。使用Java代码比较时,您可能需要包含一个误差值。 - xyz
@TomElliott:我该怎么做?有没有一种方法可以检查? - Parth Soni
1
@user1167744 Point类只是一个用于表示x,y坐标的有用类:http://docs.oracle.com/javase/1.3/docs/api/java/awt/Point.html 这将避免为x和y分别使用不同的变量。这只是简化了代码,恐怕它不会提供任何额外的方法来帮助您解决问题。 - Tom Elliott
@user1167744:看看这个链接,点是否在直线上 - nIcE cOw
3个回答

10

更新:我的原始陈述并不完全正确。使用 ptSegDist 检查一个点是否在线段上,使用 ptLineDist 检查一个点是否在直线上。 - Louis Wasserman
我想检查这个点是否在直线上,你的原始陈述对我很有帮助。 :) - Parth Soni

2
使用点到直线距离的向量形式,其中直线为x=a+tn
如果您使用非单位向量N而不是单位向量n,则d = || (a - p) - ((a - p) · N) N / (N · N) ||,这将消除一个平方根。
假设您用于描述线的浮点数数组被解释为{ x1,y1,x2,y2 },那么a =(x1,y1),N =(x2-x1,y2-y1)。
如果计算出的距离与测量或算术误差相当,则该点在直线上。同样,您不需要在模数中计算平方根,只需比较平方值即可。

1
就算法而言,一条直线(除了方程为x = 常数的垂直线)具有y = mx + b的形式。如果您的点满足该方程,则它在直线上。因此,您只需要找到直线的斜率值和其y截距,并检查点的x和y值是否满足每条直线的方程。
编辑:
正如上面的评论所指出的那样,您可以使用点斜式(其中斜率为(y2-y1)/(x2/x1))而不是斜截式。这将给您一个仅取决于y、x和线段的起点和终点的方程,这将更容易编码(因为您至少在swing中通过其起点和终点定义一条线)。我建议使用斜截式的唯一原因是因为您已经尝试在算法中使用它。

我已经在我的问题中做了什么?但是对于上述情况该怎么办? - Parth Soni
嗯,我在评论中回答了为什么对于竖直线的情况它不能工作。竖直线不是一个函数,因此不能被表示为函数。至于另一个问题,这可能与你所做的四舍五入有关。我建议使用更类似于比较浮点数的比较系统(即如果x1-x2 <.00001而不是如果x1 = x2)来对边缘情况宽容一些。 - thatidiotguy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接