我想找到直线(无限)之间的所有交点。我正在尝试更改适用于线段集的 Bentley-Ottmann 算法,但我不知道如何正确表示无限直线。第一个想法是确定可以模拟每条线的开始和结束的边界点,但我认为这是不正确的解决方案(如何找到“无限”点?)。下一个想法是使用方程来表示直线,但我不知道我是否可以使用 Bentley-Ottmann 算法(如何对线进行排序以及将事件添加到调度中?)。更重要的是,我可能需要使用除法来检测两条线的交点(同时求解一组方程)。我想避免它。
你能给我一些建议吗?
非常感谢
我想找到直线(无限)之间的所有交点。我正在尝试更改适用于线段集的 Bentley-Ottmann 算法,但我不知道如何正确表示无限直线。第一个想法是确定可以模拟每条线的开始和结束的边界点,但我认为这是不正确的解决方案(如何找到“无限”点?)。下一个想法是使用方程来表示直线,但我不知道我是否可以使用 Bentley-Ottmann 算法(如何对线进行排序以及将事件添加到调度中?)。更重要的是,我可能需要使用除法来检测两条线的交点(同时求解一组方程)。我想避免它。
你能给我一些建议吗?
非常感谢
假设您在二维欧几里得空间中执行此操作,则您的问题过度膨胀了。高中生会告诉你,线条可以用一个等式表示:
y = m*x + b
但它不能代表一条垂直线。您可以使用更通用的方程式(请参阅MathWorld):
a*x + b*y = c
在二维欧几里得空间中,有两条线:
前两种情况是方程求解。第三种情况为真,如果:
a1/a2 == b1/b2
(当然你需要处理a2 = 0or的情况b2 = 0)
忘记宾利奥特曼吧。它的聪明之处在于处理你没有的线段。
如果线是无限的,那么每一对不平行的线将只有一个交点。因此,如果 {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] 的原因之一。它使这个测试与规模无关。