Виснаження кривими Безьє

З останніх кількох днів я намагався написати власну маленьку бібліотеку анімації JavaScript. Я знаю, що знаю, що насправді ніхто не піклується про нову бібліотеку анімації, але, справа в тому, що в процесі я натрапив на криві Безьє. Я витратив пару годин на дослідження, намагаючись зрозуміти їх, під час чого я натрапив на цю свіжу статтю - “Математична інтуїція за кривими Безьє”, яка також є натхненням для цієї статті. Це математика і, здавалося б, спрямована на розумних людей, тому мені було якось важко провести час, обертаючи голову навколо концепції. Але, на щастя, врешті-решт я це зробив, і це призвело до вивчення ряду цікавих нових речей про криві Безьє, якими я дуже радий поділитися з вами.

Що ви будете вчитися

Почну з вступу до кривих, що вони собою представляють, чому вони круті, їх математичне уявлення. Не хвилюйтеся з приводу математики, хоча, чесно кажучи, я начебто смокчу математику, тому я повинен запропонувати способи, щоб пояснити це собі, і я впевнений, що "шляхи" спрацюють і на вас :).

Далі ми перейдемо до кривих Безьє. Якими вони є, і чим вони відрізняються. Їх математична формула.

Ближче до кінця ми створимо наш власний маленький механізм малювання кривих Безьє в JavaScript та SVG. Як це круто?

Криві

Мені не потрібно давати тут офіційне визначення кривої, чи не так? Всі ці лінії є кривими, подивіться на них

Криві досить солодкі, вони можуть представляти ряд речей. Як, наприклад, крива нижче показує кількість моїх підписників у Твіттері з часом.

Гаразд, добре, це схоже на довільно написаний рядок. Дозвольте додати трохи контексту.

Тепер це має дати краще уявлення про те, що воно представляє. На горизонтальній осі - кількість днів з мого приєднання до Twitter, а на вертикальній - кількість підписників, яких я набрав.

У мій перший день у Twitter у мене було 0 підписників, потім він повільно збільшувався, частину втратив, трохи здобув, а потім, як бачите, у другій половині отримав низку нових підписників. Це не єдина інформація, яку ми можемо розшифрувати з цієї кривої. Я також можу дізнатися точну кількість підписників, яких я мав у будь-який день. Справа лише в тому, щоб намалювати дві лінії.

Скажімо, я хотів би знати кількість підписників у мене на 60-й день.

Я малюю вертикальну лінію від 60 на горизонтальній осі, потім від точки, де ця лінія перетинає криву, малюю горизонтальну лінію. Ця горизонтальна лінія перетинає вертикальну вісь (вісь із кількістю послідовників) у точці. Значення цієї точки на вертикальній осі дає мені точну кількість послідовників, яких я мав на 60-й день, тобто 126.

Тепер там, де дві червоні лінії перетинаються, називається точка . На двовимірному графіку, як графік наших послідовників у Twitter, точка однозначно ідентифікується двома значеннями - горизонтальною координатою ( x ) та вертикальною координатою ( y ). Тому написання (x, y) - все, що потрібно для представлення точки. У нашому випадку червону точку, де дві червоні лінії перетинаються, можна записати як (60, 126).

(60 = x / горизонтальна координата, 126 = y / вертикальна координата)

Досить добре, що таке суть, ви це вже знали. Давайте поговоримо про криву, яка насправді є сукупністю багатьох таких точок, чи не так?

Ви берете масив даних, як на 0-й день 0 послідовників, 1-й день 50 послідовників ... 10-й день 76 послідовників ... 100-й день 500 послідовників ... і так далі. Ви перетворюєте ці дані в точки (0, 0) (1, 50) ... (10, 76) ... (100, 500) ... Ви складаєте точки на графіку, з’єднуючи їх між собою, і там у вас є крива.

Отже, для кривої потрібні точки, а для точок - відповідні значення x та y. Тому, тепер зверніть пильну увагу тут, крива може бути однозначно представлена ​​чимось, що може виплюнути для нас значення x та або y. Це “щось” - це те, що ми називаємо в математиці функцією.

У математиці є багато стандартних функцій. Розглянемо функцію синуса .

У таких функціях вибір x за нами. Ми даємо йому х , воно дає нам у . І разом ми утворюємо точку (x, y). Ми додаємо йому ще один x, це дає нам ще один y, тому і так далі ми отримуємо колекцію точок, складаємо їх і отримуємо унікальну форму.

Функція також може бути представлена ​​у параметричній формі . У параметричній формі нам не потрібно подавати частину координати точки, як це було зроблено в попередньому прикладі (x). Натомість ми надаємо параметр / змінну, який зазвичай записується як t, і для кожного t ми отримуємо як координати x, так і y , коротше ми вказуємо t, ми отримуємо точку.

Вам захочеться знати, що таке параметрична форма, коли ми говоримо про математику за кривими Безьє.

Криві Безьє

Криві Безьє - це дуже особливі криві. Математика та ідея, що стоїть за ними, мене розігнали, і ви також повинні бути готовими до того, щоб вас здули.

Оскільки ви читаєте це, я припускаю, що ви дизайнер або розробник і вже мали справу з кривими Безьє, особливо з кубічними кривими Безьє, ми дізнаємось про те, якими є криві кубічного Безьє, через секунду. Зараз ці криві використовуються в різних місцях для створення векторної графіки, шляхів анімації, кривих полегшення анімації тощо, лише тому, що ними так легко управляти . Вам не потрібно знати багато математики, анітрохи, щоб згинати ці криві до ваших примх. Подумайте, якби кривих Безьє не існувало, і людям доводилося придумувати унікальні математичні функції для кривих, скажімо, малювати векторну графіку, наприклад, шрифти, звичайно, кошмар.

Математика?

Гаразд, час для математики. Почну із загальної формули кривих Безьє, це на перший погляд досить страшно, але ми проберемось.

“Ого! Вау! Вау! Ейнштейн! ». Гей, почекай, не клацай геть. Це легко, дивись, я зробив це таким барвистим?.

Почнемо розбивати формулу. Ви можете пропустити частини, які ви вже знаєте.

B (t)

B, оскільки це крива B ezier. Як зазначалося раніше в статті про параметричну форму кривих, t - параметр. Ви підключаєте t і виходить x і y , точка. Незабаром ми побачимо, як це працює з рівнянням вище. Тут буде добре згадати, що для кривих Безьє значення t має бути від 0 до 1, включаючи обидва.

Σ / Сигма

Цей символ, Σ, в математиці називається оператором підсумовування. Це працює так: праворуч від цього символу є вираз зі змінною i, і я можу містити лише цілі значення. У верхній і нижній частині символу пишемо межі i. Для кожного значення i вираз праворуч обчислюється і додається до суми, поки i не досягне n.

Ось кілька прикладів.

Просто коротший запис для чогось довшого.

Гаразд, схоже, ми зі сигмою зрозумілі.

nCi

Це C тут, це C від перестановок та омбінацій C. Давайте проведемо імпровізований урок комбінацій. Тепер у формулі ця частина - це те, що називається біноміальним коефіцієнтом. Спосіб читання nCi такий, n Виберіть i. Тобто, враховуючи n елементів, скільки способів ви можете вибрати з них елементи (n завжди більше або дорівнює i). Гаразд, це могло б не мати великого сенсу, розгляньмо цей приклад: у мене є 3 елементи - коло, квадрат і трикутник. Отже, тут n = 3. Скількома способами я можу вибрати 2 (i = 2) елементи з 3. Мовою математики, яка буде записана як 3C2 (3 Виберіть 2). Відповідь 3.

Так само,

І коли i дорівнює 0, існує лише один спосіб вибрати 0 елементів з n, 1, щоб взагалі не вибрати жодного.

Замість того, щоб малювати ескізи та з’ясовувати відповідь на даний комбінований вираз, існує ця узагальнена формула.

P під я

Це важливий біт. У загальній формулі кривої Безьє є t, i та n. Ми насправді не торкалися того, що таке n. n - це те, що називається ступенем кривої Безьє. n - це те, що вирішує, чи є крива Безьє лінійною, квадратною, кубічною чи чимось іншим.

Ви бачите, якщо ви раніше використовували інструмент "Перо", клацніть у двох різних місцях, щоб створити дві чіткі точки, а потім керуєте кривою, яка утворюється між цими двома точками за допомогою ручок. Крива Безьє завжди буде мати принаймні дві опорні точки, а решта - контрольні точки, які використовуються для управління формою кривої. Крім того, те, що ви називаєте ручками, - це лише контрольні точки, з'єднані лінією з опорною точкою, вони просто там, щоб забезпечити кращу розумову модель. Отже, коли ви регулюєте ручки, насправді ви просто змінюєте координати контрольних точок.

Давайте позбудемось усіх аксесуарів і зосередимося на серцевині.

Крива, яку ви бачите на зображенні вище, - це кубічна крива Безьє, або іншими словами, ступінь кривої Безьє, показана вище, дорівнює 3, або в загальній формулі для кривих Безьє ви підключаєте n = 3.

n = 1 дає вам лінійну криву Безьє з двома опорними точками P0 і P1 і без контрольних точок, тому вона, по суті, закінчується прямою лінією.

n = 2 дає вам квадратну криву Безьє з двома опорними точками P0 і P2 і однією контрольною точкою P1

і так само n = 3 дає вам криву Кубіка Безьє з двома опорними точками P0 і P3 і двома контрольними точками P1 і P2. Чим вище значення n, тим складніші фігури можна намалювати.

Тепер ми сформуємо із загального рівняння рівняння для кривої Кубіка Безьє, яке передбачає заміну n = 3 у загальній формулі. Рівняння, яке ми отримаємо, буде знаходитись у змінній t, яка, як уже згадувалося раніше, є параметром, значення якого варіюється від 0 до 1. Крім того, для рівняння нам знадобляться 4 Pis (читайте: Pee eyes) P0, P1, P2 і P3. Вибір цих точок залежить від нас, врешті-решт, коли ми малюємо векторну графіку, кажемо, що за допомогою інструмента «пера» ми вибираємо положення опорних точок, а контрольні точки, чи не так? Після змін наше рівняння для кубічної кривої Безьє виглядає приблизно так.

Тут ми використовуємо невелику стислість, насправді кожна точка (P) має дві координати x і y, а також при передачі t до загального рівняння ми маємо отримати точку, яка також має координати x і y. Тому ми можемо записати наведене рівняння як

Ви збираєтеся стати свідком чогось особливого щодо цих рівнянь.

Підводячи підсумок, згадане рівняння є параметричною формою кривої Безьє з параметром t, який може містити значення, що варіюються від 0 до 1. Крива - це сукупність точок. Кожне унікальне t, яке ви передаєте B, дає унікальну точку, яка будує всю криву Безьє.

Магічна рівність полягає в тому, що коли t = 0, B (0) = P0 і коли t = 1, B (1) = P3, отже, крайні значення t, 0 і 1 дають крайні найбільші точки крива, яка, звичайно, є опорними точками. Це не справедливо лише для кубічних кривих Безьє, для кривої ступеня n B (0) = P0 і B (1) = Pn.

Для будь-якого іншого значення t від 0 до 1 (наприклад, t = 0,2 на малюнку вище) ви отримуєте точку, яка будує криву.

Оскільки ціле рівняння залежить від положення Риби (очі Пі), зміна їх положення змінює форму кривої. І саме так працюють криві Безьє.

Тепер, коли ми знаємо математику за кривими Безьє, давайте використаємо ці знання.

Я створив просту програму JavaScript, яка відображає кубічну криву Безьє, немає інтерфейсу для взаємодії з нею, оскільки я не хотів, щоб логіка зникала у всьому коді інтерфейсу, а також тому, що я ледачий. Але це не означає, що ви не можете з ним взаємодіяти :).

Це було трохи забагато, щоб взяти? Ми почали з визначення того, що таке криві, звідти перейшли до точок і того, як вони є будівельними блоками кривої. Потім ми перейшли до кривих Безьє і зрозуміли математику, щоб знайти точки, які складають криву Безьє. Сподіваюсь, ви чомусь навчились і залишили цю статтю розумнішою, ніж тоді, коли почали її читати.

Код маленького спеціального движка Cubic Bezier можна знайти в цьому репозиторії GitHub.

Оновлення: Генератор тепер може генерувати криву Безьє будь-якого ступеня, а не лише кубічні криві Безьє :).

Шукаєте більше? Я регулярно публікую в своєму блозі на nashvail.me. До зустрічі, гарного!