Я написал код, чтобы сделать это давным-давно. В проекте я работал над определенными 2D-объектами, используя кусочные границы Безье, которые были созданы как пути PostScipt.
Подход я использовал:
Пусть кривые р, д, определяется Безье контрольных точек. Они пересекаются?
Вычислить ограничивающие прямоугольники контрольных точек. Если они не перекрываются, то две кривые не пересекаются. В противном случае:
p.x (t), p.y (t), q.x (u), q.y (u) - кубические полиномы на 0 < = t, u < = 1.0. Расстояние квадрата (p.x - q.x) ** 2 + (p.y - q.y) ** 2 является многочленом на (t, u). Используйте Newton-Raphson, чтобы попытаться решить это для нуля. Отменить любые решения за пределами 0 < = t, u < = 1,0
N-R может или не может сходиться. Кривые могут не пересекаться, или N-R может просто взорваться, когда две кривые почти параллельны. Поэтому отрежьте N-R, если он не сходится после некоторого произвольного количества итераций. Это может быть довольно небольшое число.
Если N-R не сходится на решении, разделите одну кривую (скажем, p) на две кривые pa, pb при t = 0,5. Это легко, это просто вычисление средних точек, как показывает связанная статья. Затем рекурсивно проверяем (q, pa) и (q, pb) для пересечений. (Обратите внимание, что в следующем слое рекурсии q стал p, так что p и q поочередно разбиваются на каждый слой рекурсии.)
Большинство рекурсивных вызовов возвращаются быстро, потому что ограничивающие поля не перекрываются ,
Вам придется отрезать рекурсию на какой-то произвольной глубине, чтобы обрабатывать странные случаи, когда две кривые параллельны и не касаются друг друга, но расстояние между ними сколь угодно мало - возможно, только 1 ULP разницы ,
Когда вы найдете пересечение, вы не закончите, потому что кубические кривые могут иметь несколько пересечений.Таким образом, вам нужно разбить каждую кривую на пересекающейся точке и рекурсивно проверить наличие большего количества взаимосвязей между (pa, qa), (pa, qb), (pb, qa), (pb, qb).