Криві Безьє використовують у комп’ютерній графіці для малювання гладких фігур, для CSS-анімації та у багатьох інших випадках.
Це дуже проста річ, яку варто дослідити один раз, щоб надалі комфортно почуватись у світі векторної графіки та просунутих анімацій.
Ця стаття містить теоретичне, але дуже необхідне розуміння того, що таке криві Безьє, а наступна показує, як ми можемо використовувати їх для CSS анімацій.
Будь ласка, не поспішайте, щоб прочитати та зрозуміти концепцію, вона вам добре послужить.
Контрольні точки
Крива Безьє задається контрольними точками.
Їх може бути 2, 3, 4 або й більше.
Ось, наприклад, крива з двома опорними точками:
Крива з трьома точками:
Крива з чотирма точками:
Якщо придивитись до цих кривих, можна одразу помітити наступне:
-
Точки не завжди знаходяться на кривій. Це цілком нормально, як саме будується крива ми побачимо пізніше.
-
Ступінь кривої дорівнює кількості точок мінус один. Дві точки дають лінійну криву (по суті пряму лінію), три точки – квадратичну криву (параболу), чотири точки – кубічну криву.
-
Крива завжди знаходиться всередині опуклої оболонки, що утворена контрольними точками:
Остання властивість дозволяє оптимізувати пошук перетинів у комп’ютерній графіці. Криві не перетинаються, якщо їх опуклі оболонки не перетинаються. Тож попередня перевірка на перетин опуклих оболонок може вказати на відсутність перетину. Перевірка перетину опуклих оболонок значно легша, оскільки вони мають форму чотирикутника, трикутника тощо (дивіться малюнок вище), значно простіші фігури, ніж сама крива.
Головна цінність кривих Безьє для малювання в тому, що пересування контрольних точок змінює криву інтуїтивно зрозумілим чином.
Спробуйте пересунути контрольні точки за допомогою миші в наступній демонстрації:
Як ви могли помітити, крива простягається вздовж дотичних ліній 1 → 2 та 3 → 4.
Після невеликої практики стає зрозуміло, як розташувати точки, щоб отримати бажану форму. А поєднавши декілька кривих ми можемо отримати практично будь-що.
Ось деякі приклади:
Алгоритм де Кастельє
Існує математична формула для кривих Безьє, але давайте розглянемо її трохи пізніше, оскільки Алгоритм де Кастельє ідентичний математичному визначенню і наглядно показує, як вона будується.
Для початку давайте розглянемо приклад з трьох точок.
Ось демонстрація, а після неї буде пояснення.
Контрольні точки (1, 2 і 3) можна посунути мишею. Натисніть кнопку “play”, щоб запустити її.
Алгоритм де Кастельє для побудови кривої Безьє з трьох точок:
-
Намалюймо контрольні точки. У прикладі вище вони позначені як
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
додає одну точку до кривої. Множина таких точок утворює криву Безьє. Це червона парабола на малюнку вгорі.
Це був процес для 3 точок. Але те саме стосується і 4 точок.
Демонстрація для 4 точок (точки можна рухати за допомогою миші):
Алгоритм для 4 точок:
- Поєднаймо контрольні точки відрізками: 1 → 2, 2 → 3, 3 → 4. Отримаємо 3 коричневі відрізки.
- Для кожного
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-анімації, щоб описати траєкторію або швидкість анімації.
Коментарі
<code>
, для кількох рядків – обгорніть їх тегом<pre>
, для понад 10 рядків – використовуйте пісочницю (plnkr, jsbin, codepen…)