Подтвердить что ты не робот

Определение пересечения двух сегментов линии?

Возможный дубликат:
Как вы обнаруживаете, где пересекаются два сегмента линии?

Может ли кто-нибудь предоставить алгоритм или код C для определения пересечения двух сегментов линии?

4b9b3361

Ответ 1

Это действительно зависит от того, как представлены строки. Я предполагаю, что они представлены в параметрической форме

x 0 (t) = u 0 + t v 0суб >

x 1 (t) = u 1 + t v 1суб >

Здесь x, u и v - векторы (далее выделены жирным шрифтом) в & real; 2 и t & in; [0, 1].

Эти две точки пересекаются, если есть какая-то точка на обоих этих сегментах. Таким образом, если существует некоторая точка p, так что там t, где

p= x 0 (t) = u 0 + t v <суб > 0суб >

и a s такие, что

p= x 1 (s) = u 1 + s v <суб > 1суб >

И, кроме того, оба s, t & in; [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)

u 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 не должно быть слишком плохим; вам просто нужно быть осторожным, чтобы не делиться на ноль.

Надеюсь, это поможет! Если кто-то может дважды проверить математику, это будет здорово.

Ответ 2

Вы можете создать equation для двух строк, найти точку пересечения, а затем проверить, принадлежит ли она этим сегментам.