Как-то после обеда прочитал статью на gamedev.ru, а потом в комментариях к статье нашел другую и неожиданно обрел знание: как работают кривая Безье и в чем собственно суть. И чтобы не забыть, сделал эту запись в блоге.
Вообще я сразу теряюсь, когда в статье наталкиваюсь на математические формулы и сразу пытаюсь их пролистать, а тут решил вникнуть и внезапно осенило!
Линейная кривая
Самая простая кривая Безье называется «линейная кривая», хотя она не кривая, а очень даже прямая. Это банальная линейная интерполяция от точки [latex]P_0[/latex] до [latex]P_1[/latex]. Формула этой кривой вот такая: [latex]P=(1-t)*P_0+t*P_1[/latex]
Параметр [latex]t[/latex] у нас живет в пределах от нуля до единицы, заместо [latex]P[/latex] подставляем [latex]X[/latex] или [latex]Y[/latex] и получаем искомое значение.
Программистами используется та же самая формула, только в профиль (убирается лишнее умножение): [latex]P=P_0+t*(P_1-P_0)[/latex]
Квадратичная кривая
Следующая по сложности идет «квадратичная кривая». Она строится по трем точкам [latex]P_0[/latex], [latex]P_1[/latex] и [latex]P_2[/latex]. Оказывается, она представляет собой линейную интерполяцию двух простых кривых Безье по точками P0, P1 и P1, P2 соответственно. На мой взгляд звучит ужасно сложно, в голове рисуются страшные формулы, но на деле выходит довольно просто.
Формула первой кривой: [latex]A=(1-t)*P_0+t*P_1[/latex]
Формула второй кривой: [latex]B=(1-t)*P_1+t*P_2[/latex]
Линейная интерполяция: [latex]P=(1-t)*A+t*B[/latex]
После замены A и B получается такой монстр: [latex](1-t)*((1-t)*P_0+t*P_1)+t*((1-t)*P_1+t*P_2)[/latex]
Раскрываем, сокращаем, упрощаем: [latex]P=P_0*(1-t)^2+2*t*P_1*(1-t)+t^2*P_2[/latex]
Касательная к квадратичной кривой
Если записать по науке, то формула выше такая: [latex]f(t)=P_0*(1-t)^2+2*t*P_1*(1-t)+t^2*P_2[/latex]
Чтобы найти касательную к кривой Безье в любой точке t, надо вычислить производную этой функции (подсмотрено в википедии): [latex]f'(t)=2*(1-t)*(P_1-P_0)+2*t*(P_2-P_1)[/latex]
Для чего может пригодится касательная:
- поворачиваем касательную на 90 градусов, делим на длину и получаем нормаль к кривой Безье в точке t
- берем некий шаг [latex]\Delta t[/latex], вычисляем касательную для каждой t от нуля до единицы с шагом [latex]\Delta t[/latex], суммируем длину этих касательных, умноженную на [latex]\Delta t[/latex], получаем общую длину кривой Безье, точность которой зависит от [latex]\Delta t[/latex]
Если я ничего не напутал, то формула для вычисления длины выглядит вот так:
[latex]\sum\limits_{t=0}^1=|f'(t)|*\Delta t[/latex]
Затем можно рассмотреть «кубическую кривую», но это уж как-нибудь сами. Вот собственно и все, чем хотел поделиться… Не судите строго.