Код пытается найти точку пересечения двух сегментов - AB и CD.
Есть много разных способов объяснить, как он это делает, в зависимости от того, как вы интерпретируете эти операции.
Допустим, точка A имеет координаты (xa, ya), B - (xb, yb) и так далее.Допустим,
dxAB = xb - xa
dyAB = yb - ya
dxCD = xd - xc
dyCD = yd - yc
Следующая система двух линейных уравнений
| dxAB dxCD | | t | | xc-xa |
| | * | | = | |
| dyAB dyCD | | u | | yc-ya |
, если она решена для t
и u
, даст вам пропорциональное положение точки пересечения настрока AB (значение t
) и строка CD (значение u
).Эти значения будут лежать в диапазоне [0, 1]
, если точка принадлежит соответствующему сегменту, и вне этого диапазона, если точка находится вне сегмента (на линии, содержащей сегмент).
Для решения этой проблемыВ системе линейных уравнений можно использовать хорошо известное правило Крамера .Для этого нам понадобится определитель
| dxAB dxCD |
| |
| dyAB dyCD |
, который в точности равен determinant(b - a, c - d)
из вашего кода.(На самом деле, здесь у меня есть determinant(b - a, d - c)
, но это не очень важно для целей этого объяснения. Код, который вы по какой-то причине разместили, меняет местами C и D, см. Примечание PS ниже).
нам также понадобится определитель
| xc-xa dxCD |
| |
| yc-ya dyCD |
, который точно равен determinant(c-a,c-d)
из вашего кода, и определитель
| dxAB xc-xa |
| |
| dyAB yc-ya |
, который точно равен determinant(b-a,c-a)
.
Разделив эти детерминанты в соответствии с правилом Крамера, мы получим значения t
и u
, что в точности соответствует тому, что делается в опубликованном вами коде.
Затем код переходит к проверке значенийt
и u
, чтобы проверить, пересекаются ли сегменты на самом деле, т.е. принадлежат ли t
и u
диапазону [0, 1]
.И если они это сделают, он вычисляет фактическую точку пересечения, оценивая a*t+b*(1-t)
(эквивалентно, он может оценить c*u+d*(1-u)
).(Опять же, см. Примечание PS ниже).
PS В исходном коде точки D и C "поменялись местами" в том смысле, что код выполняет c - d
, где я делаюd - c
в моем объяснении.Но это не имеет значения для общей идеи алгоритма, если соблюдать осторожность со знаками.
Этот обмен точек C и D также является причиной для выражения a*(1-t)+t*b
, используемого при оценке точки пересечения,Обычно, как я объяснил, можно было увидеть что-то вроде a*t+b*(1-t)
.(У меня есть сомнения по этому поводу, хотя. Я ожидал бы увидеть a*t+b*(1-t)
там даже в вашей версии. Может быть ошибка.)
PPS Автор, если код забыл проверитьдля det == 0
(или очень близко к 0), что произойдет в случае, когда сегменты параллельны.