找到直线之间交点的算法

时间:2015-01-02 12:18:53

标签: computational-geometry line-intersection

我想找到直线(无限)之间的所有交点。我尝试改变Bentley-Ottmann算法,该算法适用于一组线段,但我不知道如何正确表示无限直线。第一个想法是确定模拟每条线的起点和终点的边界点,但我认为这是不正确的解决方案(如何找到"无限"点?)。下一个想法是使用方程来表示直线,但我不知道我是否可以使用Bentley-Ottmann算法(如何订购线路并添加事件来安排?)。还有什么我可能需要使用除法来检测两条线的交点(同时求解一组方程)。我想避免它。

你能给我一些建议吗?

非常感谢

2 个答案:

答案 0 :(得分:0)

假设您在二维欧几里得空间中这样做,那么您的问题就会过度膨胀。高中生会告诉你线条可以用等式表示:

y = m*x + b

但它不能代表垂直线。您可以使用更通用的等式(请参阅MathWorld):

a*x + b*y = c

在二维欧几里德空间中,有两条线:

  • 有一个共同点;或
  • 没有共同点:它们彼此平行;或
  • 有无数个共同点:它们是同一条线。

前两个案例是一个方程式求解。如果出现以下情况,则第三种情况属实:

a1/a2 == b1/b2

(当然,您需要处理a2 = 0b2 = 0

的情况

答案 1 :(得分:0)

忘记Bentley Ottman。它的聪明之处在于处理你没有的行

如果线是无限的,那么非平行线的每对将只有一个交点。因此,如果{L1,L2,... Ln}是所有行的集合,则算法为:

for Li, i = 1, 2, ... n-1
  for Lj, j = i+1, ... n
    if Li parallel to Lj, output <i, j, PARALLEL> 
    else output <i, j, intersection(Li, Lj)>

如果有用的话,您可以单独检查重合的平行线。

存储任意行的最强大的方法是(如前所述)系数三元组:

<A, B, C>

这样Ax + By + C = 0.标准化的方便和好的做法是A ^ 2 + B ^ 2 = 1.现在[A,B]是该线的法线单位。通过一些矢量数学,很容易看出两条线g和h的交点P由一个简单的交叉乘积给出:

P = [x/w, y/w], where [x,y,w] = [Ag, Bg, Cg] X [Ah, Bh, Ch]

请注意,对于并行(包括重合)行,您将获得w = 0,因此除法将按您的预期失败。您可以使用非常小的绝对w值来检测上面的并行情况。这是使[A,B]标准化的一个原因。它使这个测试与规模无关。