Постигая кривые Безье

Кривые Безье — это способ определения кривой по опорным точкам.

Для наглядности можно рассматривать их как график передвижения точки от начала до конца маршрута в зависимости от времени движения.

Время изменяется от 0 до 1 (до 100%). То есть мы изначально знаем время, за которое нужно переместиться из начальной точки (P0) в конечную (Pn) (конкретная величина не имеет значения). На основании этого времени можно вычислить точную траекторию — по формулам.

Берем все время за 100% (или за единицу). В момент 0 (0%) точка находится в точке P0, в момент 1 (100%) – в точке Pn. Положение точки в любой момент между этими моментами можно вычислить по формуле.

Порядок кривой всегда на 1 меньше количества контрольных точек. Рассмотрим построение пошагово, начиная с самой простой кривой.

Кривая Безье первого порядка

Простейшая кривая Безье — это обычная линия. Порядок первый – значит, контрольных точек две. Ее академическое уравнение выглядит так:

B(t) = (1-t)*P0 + t*P1

А график — вот так:

Разберем на простейшем примере. Пусть:

  • первая контрольная точка — P0 имеет координаты (0; 0),
  • вторая (и последняя) – P1 – (5; 0).

Сразу же проверим формулу.

При t = 0 (в начальный момент времени) должна получиться точка P0, а при t = 1 должна получиться точка P1.

  • B(0) = (1-0)*P0 + 0*P1 = P0 — (0; 0)
  • B(1) = (1-1)*P0 + 1*P1 = P1 — (5; 0)

А теперь найдем несколько точек между началом и концом. Тут используется сложение и умножение векторов, но в данном случае все интуитивно понятно:

  • B(0.1) = (1-0.1)*P0 + 0.1*P1 = 0.9*P0 + 0.1*P1 = 0.9*(0;0) + 0.1*(5;0) = (0.5; 0)
  • B(0.2) = (1-0.2)*P0 + 0.2*P1 = 0.8*P0 + 0.2*P1 = 0.8*(0;0) + 0.2*(5;0) = (1; 0)
  • B(0.3) = (1-0.3)*P0 + 0.3*P1 = 0.7*P0 + 0.3*P1 = 0.7*(0;0) + 0.3*(5;0) = (1.5; 0)
  • B(0.4) = (1-0.4)*P0 + 0.4*P1 = 0.6*P0 + 0.4*P1 = 0.6*(0;0) + 0.4*(5;0) = (2; 0)
  • B(0.5) = (1-0.5)*P0 + 0.5*P1 = 0.5*P0 + 0.5*P1 = 0.5*(0;0) + 0.5*(5;0) = (2.5; 0)
  • B(0.6) = (1-0.6)*P0 + 0.6*P1 = 0.4*P0 + 0.6*P1 = 0.4*(0;0) + 0.6*(5;0) = (3; 0)
  • B(0.7) = (1-0.7)*P0 + 0.7*P1 = 0.3*P0 + 0.7*P1 = 0.3*(0;0) + 0.7*(5;0) = (3.5; 0)
  • B(0.8) = (1-0.8)*P0 + 0.8*P1 = 0.2*P0 + 0.8*P1 = 0.2*(0;0) + 0.8*(5;0) = (4; 0)
  • B(0.9) = (1-0.9)*P0 + 0.9*P1 = 0.1*P0 + 0.9*P1 = 0.1*(0;0) + 0.9*(5;0) = (4.5; 0)

Все полученные точки лежат на одной прямой – это и есть кривая Безье первого порядка.

Время идет, точка движется от старта к финишу. И в любой момент времени мы точно знаем, где она находится.

Кривые Безье второго порядка и больше

В определении кривых Безье выше первого порядка кроме начала и конца появляются дополнительные опорные точки, смысл которых сложно понять с первого захода.

Непосредственно через них кривая не проходит, так зачем же они нужны?

На самом деле эти точки определяют направление движения (направление изгиба кривой) и крутизну этого изгиба.

Квадратичная кривая

Кривая Безье второго порядка, или квадратичная, задается тремя контрольными точками:

  • P0 – начало;
  • P2 – конец;
  • P1 – вспомогательная точка, определяющая изгиб кривой.

Маленький спойлер: кривая Безье второго порядка имеет форму параболы (не обязательно симметричной).

Формула у нее вот такая:

B(t) = (1 - t)2*P0 + 2t*(1 - t)*P1 + t2*P2

Проверим, что в начале и конце движения мы окажемся в точках P0 и P2 соответственно:

  • B(0) = (1 — 0)2 *P0 + 2*0*(1 — 0) * P1 + 02*P2 = P0
  • B(1) = (1 — 1)2 *P0 + 2*1*(1 — 1) * P1 + 12*P2 = P2

На примере:

  • P0 (-1; 0)
  • P2 (1; 0)
  • опорная точка P1 (0; 2):

Найдем, где будет точка через половину времени t (0.5):

B(0.5) = 0.25*P0 + 0.5*P1 + 0.25*P2 = (-0.25; 0) + (0; 1) + (0.25; 0) = (0; 1)

То есть на половине временного интервала мы окажемся в точке (0; 1).

Если найти еще несколько точек, вырисуется ровная парабола. Так, в общем, и было задумано для простоты вычислений и визуальной ясности.

Рекурсивность кривых Безье

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

Вернемся к предыдущему примеру:

  • P0 (-1; 0)
  • P2 (1; 0)
  • опорная точка P1 (0; 2):

Предположим, что мы не знаем, как построить кривую второго порядка между P0 и P2. Но мы можем построить простейшую кривую первого порядка между P0 и P1, а также между P1 и P2, пользуясь формулой:

B(t) = (1-t)*P0 + t*P1

Для каждого момента времени мы можем найти положение точки на каждой из этих кривых.

Например, в момент времени 0.25 соответствующие точки Q0 и Q1 будут в таких позициях:

Между этими точками тоже можно построить кривую первого порядка.

Магия заключается в том, что точка на этой кривой в момент времени t = 0.25 соответствует точке на искомой кривой второго порядка в этот же момент времени.

Распишем чуть подробнее.

Мы хотим найти точку на кривой второго порядка P0-P11-P2 в момент времени t.

  • Этому моменту на кривой P0-P1 соответствует точка Q0;
  • А на кривой P1-P2 – точка Q1.

Искомая точка – это точка на кривой Q0-Q1, соответствующая моменту времени t.

Этот рекурсивный алгоритм построения кривой Безье носит имя Поля де Кастельжо.

Кубическая кривая

Кривая Безье третьего порядка, или кубическая кривая, определяется уже четырьмя опорными точками – началом, концом и двумя вспомогательными, через которые она не будет непосредственно проходить.

Две вспомогательные точки снова определяют направление и крутизну изгибов кривой.

Формула кубической кривой еще сложнее:

B(t) = (1 - t)3*P0 + 3t*(1-t)2*P1 + 3t2*(1 - t)*P2 + t3*P3

Вы можете попробовать эту кривую рассчитать самостоятельно.

Обратите внимание, ее тоже можно получить рекурсивно!

Найти точку кривой третьего порядка в момент времени t можно по следующему алгоритму:

  1. Строим кривые первого порядка P0-P1, P1-P2, P2-P3
  2. Находим на них соответствующие t точки Q0, Q1, Q2
  3. Строим кривые первого порядка Q0-Q1 и Q1-Q2
  4. Находим на них соответствующие t точки R0 и R1
  5. Строим кривую первого порядка R0-R1
  6. Находим на ней точку, соответствующую t.

Зачем все это нужно?

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

Кривые Безье используются в описаниях шрифтов TrueType, в SVG, GIMP и других графических форматах, в 3D-графике. Они используются даже в CSS для описания плавности анимации.

В общем, штука очень полезная.

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *