Алгоритм вставки точек в кусочно-кубический путь Безье

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

Кто-нибудь знает библиотеку или ссылку на алгоритмы Безье (вставка, оптимизация, де Кастельжау...)?

Ответ 1

Это называется "проблемой вставки узла". Для кривых Безье алгоритм де Кастеляу даст вам правильный ответ. Вот простой алгоритм для степени 3 Безье.

Предположим, вы хотите вставить узел на долю t пространства параметров внутри кривой Безье, определяемой P0, P1, P2, P3. Вот что вы делаете:

P0_1 = (1-t)*P0 + t*P1
P1_2 = (1-t)*P1 + t*P2
P2_3 = (1-t)*P2 + t*P3

P01_12 = (1-t)*P0_1 + t*P1_2
P12_23 = (1-t)*P1_2 + t*P2_3

P0112_1223 = (1-t)*P01_12 + t*P12_23

Тогда ваш первый Безье будет определяться: P_0, P0_1, P01_12, P0112_1223; ваш второй Bézier определяется: P0112_1223, P12_23, P2_3, P3.

Геометрическая интерпретация проста: вы разбиваете каждый сегмент многоугольника Безье на фракции t, затем соединяете эти точки разделения в новом многоугольнике и итерации. Когда вы остаетесь с 1 точкой, эта точка лежит на кривой, а предыдущие/следующие точки разделения образуют предыдущий/следующий многоугольник Безье. Тот же алгоритм также работает для кривых Безье Безье.

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

Ответ 2

Вы также можете воспользоваться математическим подходом.

Квабическая кривая Безье с контрольными точками p_1,p_2,p_3,p_4 может быть записана как:

b(t)=(1-t)^3 p_1+3t(1-t)^2 p_2+3t^2 (1-t) p_3+t^3 p_4

Его производная w.r.t. t есть

\frac{\partial b}{\partial t} = 3(1-t)^2 (p_2-p_1 )+6t(1-t)(p_3-p_2 )+3t^2 (p_4-p_3 )

Чтобы ограничить кривую от t0 до t1, вы получите новые контрольные точки q_1,q_2,q_3,q_4:

q_1=b(t_0),q_4=b(t_1)

q_2=q_1+\frac{1}{3}(t_1-t_0)\frac{\partial{b}}{\partial{t}}_{(t=t_0)}

q_3=q_4-\frac{1}{3}(t_1-t_0)\frac{\partial{b}}{\partial{t}}_{(t=t_1)}

Доказательство

Подставив

s=\frac{t-t_0}{t_1-t_0}

<Т411 >

Получаем

\frac{\partial b}{\partial s} = \frac{\partial b}{\partial t} \frac{\partial t}{\partial s} = (t_1-t_0) \frac{\partial b}{\partial t}

Первая и последняя точки подкринеты - это первая и последняя новые контрольные точки

q_1=b(t_0),q_4=b(t_1)

И тангенс в этих точках

\frac{\partial{b}}{\partial{s}}_{(s=0)}=(t_1-t_0)\frac{\partial{b}}{\partial{t}}_{(t=t_0)}=3(q_2-q_1)

\frac{\partial{b}}{\partial{s}}_{(s=1)}=(t_1-t_0)\frac{\partial{b}}{\partial{t}}_{(t=t_1)}=3(q_4-q_3)

Итак,

q_2=q_1+\frac{1}{3}(t_1-t_0)\frac{\partial{b}}{\partial{t}}_{(t=t_0)}

q_3=q_4-\frac{1}{3}(t_1-t_0)\frac{\partial{b}}{\partial{t}}_{(t=t_1)}

Ответ 3

Добавление этого для полноты.

Исходная реализация многих операций пути Безье может быть найдена внутри GIMP исходного кода, в gimpbezierstroke.c. Для справки о вставке нового якоря выполните поиск gimp_bezier_stroke_anchor_insert.