检查是一个点(x,y)是在直线上绘制的两个点之间

我在两点A(x,y)— B(x,y)之间绘制了一条线。现在我有第三个点C(x,y)。 我想知道如果C位于A和B之间的线上。我想用java语言来做。 我找到了几个类似的答案。 但是,都有一些问题,没有人是完美的。

 if (distance(A, C) + distance(B, C) == distance(A, B)) return true; // C is on the line. return false; // C is not on the line. 

要不就:

 return distance(A, C) + distance(B, C) == distance(A, B); 

这种方式很简单。 如果C位于AB线上,您将得到以下情形:

 AC------B 

并且,无论它在哪一条线上, dist(AC) + dist(CB) == dist(AB) 。 对于任何其他情况,你有一个描述的三角形和’dist(AC)+ dist(CB)> dist(AB)’:

 A-----B \ / \ / C 

事实上,如果C位于外推线上,这甚至可以工作:

 C---A-------B 

只要距离保持不合格。 距离dist(AB)可以计算为:

  ___________________________ / 2 2 V (Ax - Bx) + (Ay - By) 

请记住浮点运算的固有限制(有限精度)。 您可能需要选择“足够接近”的测试(例如,小于百万分之一的错误)以确保平等的正确运行。

注意! 数学只!

尝试这个!

你可以尝试这个公式。 把你的A(x1, y1)B(x2, y2)坐标放到公式中,然后你会得到像

 y = k*x + b; // k and b - numbers 

然后,任何满足这个等式的点都将在你的线上。 要检查C(x, y)是否在A(x1, y1)B(x2, y2) ,请检查: (x1x>x2 && y1>y>y2) (x1x>x2 && y1>y>y2)

 A(2,3) B(6,5) 

线方程:

 (y - 3)/(5 - 3) = (x - 2)/(6 - 2) (y - 3)/2 = (x - 2)/4 4*(y - 3) = 2*(x - 2) 4y - 12 = 2x - 4 4y = 2x + 8 y = 1/2 * x + 2; // equation of line. k = 1/2, b = 2; 

让我们检查C(4,4)在这条线上。

 2<4<6 & 3<4<5 // C between A and B 

现在把C坐标放到等式中:

 4 = 1/2 * 4 + 2 4 = 2 + 2 // equal, C is on line AB 

PS:正如@paxdiablo所写,你需要在计算之前检查线是水平还是垂直。 检查一下

 y1 == y2 || x1 == x2 

我相信最简单的是

 // is BC inline with AC or visa-versa public static boolean inLine(Point A, Point B, Point C) { // if AC is horizontal if (Ax == Cx) return Bx == Cx; // if AC is vertical. if (Ay == Cy) return By == Cy; // match the gradients return (Ax - Cx)*(Ay - Cy) == (Cx - Bx)*(Cy - By); } 

您可以通过将x值的差除以y值的差来计算梯度。

注意:如果您在屏幕上绘制C,则会有不同的测试来查看A是否出现在A和B之间的线上。 数学假设A,B,C是无限小的点。 实际上非常小到表示错误。

上述答案不必要地复杂化。 最简单的如下。

  1. 如果(x-x1)/(x2-x1)=(y-y1)/(y2-y1)= alpha(常数),那么点C(x,y)将位于第1和第2位之间的线上。

  2. 如果alpha <0.0,则C在点1的外部。

  3. 如果alpha> 1.0,则C在点2的外部。
  4. 最后,如果alpha = [0,1.0],则C在1和2的内部。

希望这个答案有所帮助

我认为这里的所有方法都存在缺陷,因为它们并没有尽可能严格地处理舍入错误。 基本上,所描述的方法将使用一些简单的算法告诉您您的点是否足够接近线,并且它或多或少会精确。

为什么精确度很重要? 因为这是op提出的问题。 对于计算机程序而言,在一条线上没有点这样的东西,在一条线的epsilon中只有一点,并且需要记录该epsilon的内容。

让我们来说明问题。 使用距离比较算法:

假设一个段从(0,0)到(0,2000),我们在我们的应用程序中使用浮点数(它有大约7位小数的​​精度),我们测试一个点(1E-6,1000)是否是在线还是没有。

从段的任一端到该点的距离是1000.0000000005或1000 + 5E-10,因此,与该点之间的距离的增加的差值是大约1E-9。 但是这些值都不能存储在具有足够精确度的浮点数上,并且该方法将返回true

如果我们使用更精确的方法,比如计算到线中最近点的距离,它会返回一个值,浮点数具有足够的精度来存储,我们可以根据可接受的epsilon返回false。

我在示例中使用了浮点数,但同样适用于任何浮点类型,例如double。

一种解决方案是使用BigDecimal和任何你想要的方法,如果招致性能和内存命中不是问题。

比比较浮点距离更精确的方法,更重要的是, 一致精确,尽管计算成本较高,但是计算到线中最近点的距离。

点和线段之间的最短距离

看起来我正在分裂头发,但我之前不得不处理这个问题。 链接几何运算时会出现问题。 如果你不控制你正在处理什么样的精算损失,最终你会遇到困难的错误,这将导致你严格地对代码进行推理以解决它们。

一个简单的方法,我相信将检查3点形成的角度。 如果角度ACB是180度(或接近它,取决于你想要的准确度),那么点C在A和B之间。