有人可以提供算法或C代码来确定两个线段是否相交吗?
答案 0 :(得分:94)
这实际上取决于线条的表示方式。我将假设你以参数形式表示它们
x 0 (t)= u 0 + t v 0 < /子> 强>
x 1 (t)= u 1 + t v 1 < /子> 强>
此处, x , u 和 v 是ℜ 2 和t∈[0,1]。
如果在这两个线段上都有一些点,则这两个点相交。因此,如果有一点 p ,那么就有一个t
p = x 0 (t)= u 0 + t的 v <子> 0 子> 强>
和s
p = x 1 (s)= u 1 + s的 v <子> 1 子> 强>
此外,s,t∈[0,1],然后两条线相交。否则,他们没有。
如果我们将这两个等式结合起来,我们就得到了
u 0 + t v 0 = u 1 + s v 1
或者,相当于
u 0 - u 1 = s v 1 - t v 0
u 0 =(x 00 ,y 00 )
你 1 =(x 10 ,y 10 )
v 0 =(x 01 ,y 01 )
v 1 =(x 11 ,y 11 )
如果我们以矩阵形式重写上面的表达式,我们现在有了
| x00 - x10 | | x11 | | x01 |
| y00 - y10 | = | y11 | s - | y01 | t
这相当于矩阵表达式
| x00 - x10 | | x11 x01 | | s|
| y00 - y10 | = | y11 y01 | |-t|
现在,我们有两个案例需要考虑。首先,如果这个左侧是零向量,那么就有一个简单的解决方案 - 只需设置s = t = 0并且点相交。否则,只有当右侧矩阵是可逆的时,才有一个独特的解决方案。如果我们让
| x11 x01 |
d = det(| y11 y01 |) = x11 y01 - x01 y11
然后是矩阵的逆矩阵
| x11 x01 |
| y11 y01 |
由
提供 | y01 -x01 |
(1/d) | -y11 x11 |
请注意,如果行列式为零,则不定义此矩阵,但如果这是真的,则表示这些行是平行的,因此不相交。
如果矩阵是可逆的,那么我们可以通过左乘这个矩阵求解上述线性系统:
| s| | y01 -x01 | | x00 - x10 |
|-t| = (1/d) | -y11 x11 | | y00 - y10 |
| (x00 - x10) y01 - (y00 - y10) x01 |
= (1/d) | -(x00 - x10) y11 + (y00 - y10) x11 |
所以这意味着
s = (1/d) ((x00 - x10) y01 - (y00 - y10) x01)
t = (1/d) -(-(x00 - x10) y11 + (y00 - y10) x11)
如果这两个值都在[0,1]范围内,则两个线段相交,您可以计算交点。否则,它们不相交。另外,如果d为零,那么这两条线是平行的,这可能是也可能不是您感兴趣的。用C编写这个应该不会太糟糕;你只需要注意不要除以零。
希望这有帮助!如果有人可以仔细检查数学,那就太棒了。
答案 1 :(得分:0)
您可以为两条线构建equation,找到交叉点,然后检查它是否属于这些线段。