Кривые Безье используются в компьютерной графике для рисования плавных изгибов, в CSS-анимации и много где ещё.
Это очень простая вещь, которую стоит изучить один раз, а затем чувствовать себя комфортно в мире векторной графики и продвинутых анимаций.
Эта статья даёт теоретическое, но очень необходимое представление о том, что такое кривые Безье, в то время как следующая показывает, как мы можем использовать их для CSS-анимаций.
Пожалуйста, найдите время, чтобы прочитать и понять концепцию, это сослужит вам хорошую службу.
Опорные точки
Кривая Безье задаётся опорными точками.
Их может быть две, три, четыре или больше. Например:
По двум точкам:
По трём точкам:
По четырём точкам:
Если вы посмотрите внимательно на эти кривые, то «на глазок» заметите:
-
Точки не всегда на кривой. Это совершенно нормально, как именно строится кривая мы рассмотрим чуть позже.
-
Степень кривой равна числу точек минус один. Для двух точек – это линейная кривая (т.е. прямая), для трёх точек – квадратическая кривая (парабола), для четырёх – кубическая.
-
Кривая всегда находится внутри выпуклой оболочки, образованной опорными точками:
Благодаря последнему свойству в компьютерной графике можно оптимизировать проверку пересечения двух кривых. Если их выпуклые оболочки не пересекаются, то и кривые тоже не пересекутся. Таким образом, проверка пересечения выпуклых оболочек в первую очередь может дать быстрый ответ на вопрос о наличии пересечения. Проверить пересечение или выпуклые оболочки гораздо проще, потому что это прямоугольники, треугольники и т.д. (см. рисунок выше), гораздо более простые фигуры, чем кривая.
Основная ценность кривых Безье для рисования в том, что, двигая точки, кривую можно менять, причём кривая при этом меняется интуитивно понятным образом.
Попробуйте двигать точки мышью в примере ниже:
Как можно заметить, кривая натянута по касательным 1 → 2 и 3 → 4.
После небольшой практики становится понятно, как расположить точки, чтобы получить нужную форму. А, соединяя несколько кривых, можно получить практически что угодно.
Вот некоторые примеры:
Алгоритм «де Кастельжо»
Есть математическая формула для кривых Безье, но давайте рассмотрим её чуть позже, потому что Алгоритм де Кастельжо идентичен математическому определению кривой и наглядно показывает, как она строится.
Рассмотрим его на примере трёх точек (точки 1,2 и 3 можно двигать). Нажатие на кнопку «play» запустит демонстрацию.
Построение кривой Безье с 3 точками по «алгоритму де Кастельжо»:
-
Рисуются опорные точки. В примере это:
1
,2
,3
. -
Строятся отрезки между опорными точками в следующем порядке 1 → 2 → 3. На рисунке они коричневые.
-
Параметр
t
«пробегает» значения от0
до1
. В примере использован шаг0.05
, т.е. в цикле0, 0.05, 0.1, 0.15, ... 0.95, 1
.Для каждого из этих значений
t
:-
На каждом из коричневых отрезков берётся точка, находящаяся на расстоянии, пропорциональном
t
, от его начала. Так как отрезков два, то и точек две.Например, при
t=0
– точки будут в начале, приt=0.25
– на расстоянии в 25% от начала отрезка, приt=0.5
– 50% (на середине), приt=1
– в конце отрезков. -
Эти точки соединяются. На рисунке ниже соединяющий их отрезок изображён синим.
-
При t=0.25 |
При t=0.5 |
---|---|
-
На получившемся синем отрезке берётся точка на расстоянии, соответствующем
t
. То есть, дляt=0.25
(левый рисунок) получаем точку в конце первой четверти отрезка, дляt=0.5
(правый рисунок) – в середине отрезка. На рисунках выше эта точка отмечена красным. -
По мере того, как
t
«пробегает» последовательность от0
до1
, каждое значениеt
добавляет к кривой точку. Совокупность таких точек для всех значений образует кривую Безье. Она красная и имеет параболическую форму на картинках выше.
Был описан процесс для построения по трём точкам. Но то же самое происходит и с четырьмя точками.
Демо для четырёх точек (точки можно двигать):
Алгоритм для 4 точек:
-
Точки по порядку соединяются отрезками: 1 → 2, 2 → 3, 3 → 4. Получается три коричневых отрезка.
-
Для
t
на отрезке от0
до1
:- На отрезках берутся точки, соответствующие текущему
t
, соединяются. Получается два зелёных отрезка . - На этих отрезках берутся точки, соответствующие текущему
t
, соединяются. Получается один синий отрезок. - На синем отрезке берётся точка, соответствующая текущему
t
. При запуске примера выше она красная.
- На отрезках берутся точки, соответствующие текущему
-
Эти точки вместе описывают кривую.
Алгоритм является рекурсивным и может быть обобщён на любое количество опорных точек.
Дано N опорных точек:
- Соединяем их, чтобы получить N-1 отрезков.
- Затем для каждого
t
от0
до1
берём точку на каждом отрезке на расстоянии пропорциональномt
и соединяем их. Там будет N-2 отрезков. - Повторяем 2 шаг, пока не останется одна точка.
Эти точки образуют кривую.
Запускайте и приостанавливайте примеры, чтобы ясно увидеть отрезки и то, как строится кривая.
Кривая, которая выглядит как y=1/t
:
Зигзагообразные опорные точки тоже работают нормально:
Создание петли возможно:
Негладкая кривая Безье (да, это тоже возможно):
Если в описании алгоритма есть что-то непонятное, посмотрите «живые» примеры выше, они наглядно показывают, как строится кривая.
Поскольку алгоритм является рекурсивным, мы можем построить кривые Безье любого порядка, используя 5, 6 или более опорных точек. Но на практике много точек не так полезны. Обычно мы берём 2-3 точки, а для сложных линий склеиваем несколько кривых. Это проще для разработки и расчёта.
Для задания кривой Безье используются опорные точки. Как видим, они не находятся на кривой, кроме первой и последней.
Иногда перед нами стоит другая задача: нарисовать кривую через несколько точек, чтобы все они были на одной гладкой кривой. Эта задача называется интерполяцией, и она за рамками нашего изложения.
Для таких кривых существуют математические формулы, например, полином Лагранжа. В компьютерной графике сплайн-интерполяция часто используется для построения плавных кривых, соединяющих множество точек.
Математика
Кривая Безье может быть описана с помощью математической формулы.
Как мы видели, на самом деле нет необходимости её знать, большинство людей просто рисуют кривую, перемещая точки с помощью мыши. Но если вы увлекаетесь математикой – вот она.
Координаты кривой с опорными точками Pi
: первая опорная точка имеет координаты P1 = (x1, y1)
, вторая: P2 = (x2, y2)
и т.д., описываются уравнением, зависящим от параметра t
на отрезке [0,1]
.
-
Формула для 2-х точечной кривой:
P = (1-t)P1 + tP2
-
Для 3 опорных точек:
P = (1−t)2P1 + 2(1−t)tP2 + t2P3
-
Для 4 опорных точек:
P = (1−t)3P1 + 3(1−t)2tP2 +3(1−t)t2P3 + t3P4
Это векторные уравнения. Другими словами, мы можем поставить x
и y
вместо P
, чтобы получить соответствующие координаты.
Например, 3-точечная кривая образована точками (x,y)
, рассчитанными как:
x = (1−t)2x1 + 2(1−t)tx2 + t2x3
y = (1−t)2y1 + 2(1−t)ty2 + t2y3
Вместо x1, y1, x2, y2, x3, y3
мы должны поместить координаты 3 опорных точек, а затем при перемещении t
от 0
до 1
для каждого значения t
мы получим (x,y)
кривой.
Например, если опорными точками являются (0,0)
, (0.5,1)
и (1,0)
, уравнения становятся:
x = (1−t)2 * 0 + 2(1−t)t * 0.5 + t2 * 1 = (1-t)t + t2 = t
y = (1−t)2 * 0 + 2(1−t)t * 1 + t2 * 0 = 2(1-t)t = –2t2 + 2t
Теперь, в то время как t
«пробегает» от 0
до 1
, набор значений (x, y)
для каждого t
образует кривую для таких опорных точек.
Итого
Кривые Безье задаются опорными точками.
Мы рассмотрели два определения кривых:
- Через математическую формулу.
- Использование процесса рисования: алгоритм де Кастельжо.
Их удобство в том, что:
- Можно рисовать плавные линии с помощью мыши, перемещая опорные точки.
- Сложные формы могут быть сделаны из нескольких кривых Безье.
Применение:
- В компьютерной графике, моделировании, в графических редакторах. Шрифты описываются с помощью кривых Безье.
- В веб-разработке – для графики на Canvas или в формате SVG. Кстати, все живые примеры выше написаны на SVG. Фактически это один SVG-документ, к которому точки передаются параметрами. Вы можете открыть его в отдельном окне и посмотреть исходник: demo.svg.
- В CSS-анимации для задания траектории или скорости передвижения.