忘记宾利奥特曼吧。它的聪明之处在于处理你没有的线段。
如果线是无限的,那么每一对不平行的线将只有一个交点。因此,如果 {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] 的原因之一。它使这个测试与规模无关。