确定两个线段是否相交?

时间:2011-02-12 10:13:06

标签: algorithm math geometry

  

可能重复:
  How do you detect where two line segments intersect?

有人可以提供算法或C代码来确定两个线段是否相交吗?

2 个答案:

答案 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,找到交叉点,然后检查它是否属于这些线段。