Я написал код, чтобы сделать это давным-давно. Проект, над которым я работал, определил двухмерные объекты, используя кусочные границы Безье, которые были сгенерированы как пути PostScipt.
Подход, который я использовал, был:
Пусть кривые p, q определены контрольными точками Безье. Они пересекаются?
Вычислить ограничивающие рамки контрольных точек. Если они не перекрываются, то две кривые не пересекаются. В противном случае:
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).
Используйте Ньютона-Рафсона, чтобы попытаться решить это за ноль. Откажитесь от любых решений за пределами 0 <= t, u <= 1,0 </p>
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).