Обнаружение "Кинков" в параллельных линиях к кривым Безье

Я надеялся, что кто-то сможет помочь мне вычислить недорогостоящий метод обнаружения перегибов в линии, проведенной параллельно кривой Безье, как вы можете видеть здесь.

Kink in Line Parallel to Bezier Curve

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

Извините, если я использую неправильные термины. Но насколько я понимаю, как я позиционирую эти сегменты, это определить единичный вектор сегментов кривой Безье (желтый) и умножить его на смещение и найти нормальный вектор для создания двух новых начальных и конечных точек для сегмента смещения (белый).

Математика не мой сильный костюм, поэтому я надеюсь, что кто-то может дать мне толчок в правильном направлении.

EDIT: изображение действительно было изменено по HTML, поэтому, если вам нелегко увидеть, о чем я говорю, здесь прямая ссылка: http://i.stack.imgur.com/xtils.png

Ответ 1

В первом приближении вычислите радиус кривизны вашего Безье кривая. Если смещение больше или равно радиусу кривизны, вы должны искать излом.

В частности, для кубического Безье с контрольными точками P0, P1, P2, P3:

B(t) = P0 * (1-t)^3 + P1 * 3*t*(1-t)^2 + P2 * 3*t^2*(1-t) + P3 * t^3
-> B'(t)  = (P1-P0) * 3*(1-t)^2 + (P2-P1) * 6*t*(1-t) + (P3-P2) * 3*t^2 
-> B''(t) = (P2+P0-2*P1) * 6*(1-t) + (P3+P1-2*P2) * 6*t

let:  cross2d(p, q) = p.x*q.y - p.y*q.x
then, radius of curvature = |B'(t)|^3 / cross2d(B'(t), B''(t))

Я оставил радиус кривизны в подписанной форме; знак должен указывать сторону кривой, на которой вы можете ожидать излома.

Примечание: вы можете иметь нулевой радиус кривизны или бесконечный радиус кривизны; лучше сравнить |B'(t)|^3 с signed_offset * cross2d(B'(t), B''(t)).