Математика в геймдеві. Що таке кватерніони та як їх використовують при розробці ігор

Ми продовжуємо серію текстів «Математика в геймдеві» — цикл про цікаві та конкретні математичні концепції, які можна використати при розробці ігор. У минулих публікаціях ми писали про діаграми Вороного та інтерполяцію. Цього ж разу розповімо про кватерніони.

Цей математичний об’єкт — потужний інструмент при розробці графіки та фізики в іграх. Втім, склалася цікава ситуація. Досвідчені розробники стверджують, що хоч майже кожен користувач Unity стикається з кватерніонами у своїй роботі, далеко не усі це усвідомлюють. Тому ми детальніше розглянемо, що ж це таке, хто перший прийшов до думки кватерніонів та як їх застосовувати у геймдеві.

Нижче — невеличкий екскурс в історію кватерніонів. Якщо вам цікаво прочитати саме про прикладний аспект цього об’єкту, радимо перейти одразу до розділу «Кватерніони та геймдев».

Історія кватерніонів: поети, двобій та дублінський міст

Кватерніон це чотиривимірне гіперкомплексне число, яке активно використовується, наприклад, для опису просторових поворотів у 3D-графіці. Але для того, щоб зрозуміти, як вони виникли та що це таке, потрібно зробити кілька кроків назад у часі. Як мінімум, до моменту появи комплексних чисел, а, можливо, ще далі — до перших квадратних рівнянь.

Ще в Месопотамії вміли розв’язувати певні квадратні рівняння — першим задокументованим прикладом рішення вважається Берлінський папірус 6619, якому за різними оцінками від 4 до 3,5 тисяч років. Трошки згодом греки знайшли геометричні та алгебраїчні методи розв’язання «квадратів», а індуси та араби пішли далі, замахнувшись на кубічні рівняння. В XI столітті поет та математик Омар Хаям розв’язав кубічну задачу за допомогою перетину парабол та кіл (а ще, ймовірно, написав про це життєствердного вірша). Втім, він помилково припустив, що загальної формули для кубів не існує.

Берлінський папірус 6619

Головний науковий прорив стався в часи Раннього Ренесансу — і насправді ця детективна історія заслуговує на велику голлівудську екранізацію. Тут є зухвалі спадкоємці таємного знання, вундеркінди, епічна математична дуель та навіть зрада.

На початку XVI століття італійський математик Сципіон дель Ферро знайшов рішення для x3 + mx = n, де m та n більше за нуль. У його часи існувала практика тримати такі відкриття в таємниці і Ферро перед смертю показав метод лише своєму учню Антоніо Фіору. Останній, схоже, був людиною не дуже гарною — відкриття залишив у таємниці, але почав їм активно вихвалятися серед інших математиків.

Формула Сципіона для x3 + mx = n

Поставив на місце Фіору інший видатний італієць — Нікколо Фонтана. Сьогодні цього чоловіка б називали self-made man. У його сім’ї не було грошей на школу, тому він вчив математику сам. Ба більше, під час Італійських війн його рідне місце захопили французи і хлопчик, якому тоді було лише шість, отримав від оккупантів поранення язика та гортані. Решту життя розмовляти йому було дуже складно. Власне, так і з’явився його більш відомий псевдонім Тарталья (від італійського tartaglia — заїка).

Та це не завадило досягти йому неабияких висот у науці. У 1530 році Тарталья самостійно знайшов метод розв’язання рівняння виду x3 + mx2 = n, а через п’ять років хвалько Фіора викликав його на математичний двобій. За правилами інтелектуальної сутички, супротивники пропонували один одному 30 задач і давали на пошук відповідей до 50 днів. Звісно, Фіора не знав, що його опонент вже навчився розв’язувати рівняння третього ступеня і майже усі його «атаки» були кубічними. Тарталья ж запропонував проблеми з різних розділів математики. За легендою, перемога останнього була феноменальною: лише за дві години Нікколо розв’язав усі задачі Фіори, а Антоніо, врешті-решт, жодної.

Дуже скоро про цей двобій дізнався Джироламо Кардано. Цей пан був ніби втіленням усіх стереотипів про геніїв: хворобливе, депресивне дитинство; ексцентричний, конфронтаційний характер; майже повна відсутність друзів та надзвичайний талант до математики, фізики, філософії та інженерної справи. Щоб зрозуміти, наскільки різнобічним був Кардано можна навести лише один приклад: він починав працювати лікарем, але паралельно вивчав математику. Лише кілька років йому знадобилося, щоб у книжці «Про азартні ігри» закласти основи теорії ймовірності, закону великих чисел та деяких питань комбінаторики.

Хоча в цій історії Кардано є, скоріше, негідником. Після славетної перемоги Фонтано він вмовив його розкрити метод розв’язання кубічних рівнянь. Примітно, що Нікколо зробив це у формі поеми, а сам Кардано обіцяв залишити метод у таємниці. Та, звісно ж, цю обіцянку він не виконав. У 1545 році Кардано видав «Ars Magna» — перший у світі трактат з алгебри латинкою, до якого включив і здобутки колеги. Це викликало дискусію на роки та десятиліття, але все одно формула для аналітичного розв’язку будь-якого кубічного рівняння вигляду ax3 + bx2 + cx + d = 0 зараз називається «формулою Кардано».

Втім, куди важливіше за його зраду буде уточнення, що для свого методу Тарталья не використовував комплексних чисел. Кордано ж був першим, хто зрозумів — можна працювати з чимось, що є більш загальними за реальні числа. У своїх працях він вдало маніпулював комплексними числами, хоча й було з цим кілька проблем. По-перше, Кордано не до кінця розумів власну математику. По-друге, комплексні числа здавалися йому примарними та беззмістовними. По-третє, використання уявних чисел він назвав «психічними тортурами».

З часом комплексні числа починають просочуватися буквально всюди. Наприклад, їх використовують для визначення координат точки на площині: одна координата — дійсне число, інша — уявна частина. Тобто, з’являється таке поняття, як комплексна площина.

У XIX столітті один з кращих математиків свого часу Вільям Ровен Гамільтон знав, що комплексними числами можна описати точку на площині. Знав він і про те, що такі числа можна складати та перемножувати, використовуючи певні геометричні операції. Тому Гамільтон замислився над описом точки у тривимірному просторі. Для цього він придумав потрійні числа. Тобто, якщо комплексні мали вигляд a+bi, то потрійні — a+bi+сj.

З цим виникли певні проблеми — потрійні числа можна було складати чи віднімати один від одного. А от як їх перемножувати Гамільтон зрозуміти не міг. В одному з листів сину Арчибальду математик згадує:

«Кожного ранку на початку жовтня 1843 року, коли я спускався снідати, твій брат Вільям Едвін та ти питали в мене: ну, тату, ти вже вмієш множити потрійні? На що я завжди був змушений відповідати, сумно хитаючи головою: ні, можу лише додавати та віднімати».

Про усвідомлення Гамільтоном помилки існує історія, яка за красою не поступається двобою між італійськими математиками. Він нібито гуляв з дружиною по Королівському каналу в Дубліні, а коли вони дійшли до моста Брум Брідж — науковець чомусь все зрозумів. Він не міг перемножити потрійні числа, тому що вони мали складатися з чотирьох компонентів. За легендою, Гамільтонон прямо там, на камінні моста, надряпав своє визначення кватерніона: i2 = j2 = k2 = ijk = —1. Якщо коротко, то помилка його була в тому, що потрібні не лише координати точки в просторі, а ще й кут повороту. Тобто у кватерніона чотири компоненти: X, Y, Z та W, перші три — вісь повороту, а останній — його кут.

Кватерніони та геймдев

У XX столітті кватерніони активно намагалися використовувати у квантовій механіці та теорії відносності, але особливо корисними вони виявилися у сучасній комп’ютерній графіці. Особливо при створенні ігор.

«Квартеріони використовуються кожним юніті девелопером. Та й в цілому усіма, хто працює із 3D-простором. Річ йде про обертання. Те що людина бачить осі повороту — це не так. Це обгортка для юзера. Насправді саме поворот у 3D-просторі — чотиривимірний. Четвертий вимір використовується для того, щоб перші три не залежали один від іншого. Тому що, наприклад, при повороті по осі Y осі X та Z змінюють свої напрямки відносно глобальних осей», — зазначає Unity-розробник Антон Будничук.

Засновниця Unity Tech Learn Arcueid D’athemon додає, що кватерніони є одним з найрозповсюдженіших способів опису оберту об’єкта. Але часто девелопери ігнорують їх свідоме використання, оскільки не до кінця розуміють, як і для чого їх можна використовувати. Розробниця навела для нас кілька показових прикладів — нижче у блоках цитат її пряма мова.

«Кватерніони можна використовувати для афінних перетворень. Якщо не вдаватись у подробиці того що таке афінні перетворення, то можна навести приклад обертання Vector3 — завдяки кватерніонам ми можемо змінювати напрям руху на потрібний нам кут».
Vector3[] points = new Vector3[]
        {
            new Vector3(-1, -1, 0),
            new Vector3(1, -1, 0),
            new Vector3(0, 1, 0)
        };

        //Creates a Quaternion rotation of 5 degrees around the Z axis
        Quaternion rotation = Quaternion.AngleAxis(5, Vector3.forward);

        //Loop through the array of Vector3s and apply the rotation
        for (int n = 0; n < points.Length; n++)
        {
            Vector3 rotatedPoint = rotation * points[n];
            //Output the new rotation values
            Debug.Log("Point " + n + " rotated: " + rotatedPoint);
        }

Також Arcueid D’athemon зазначила, що багато хто з розробників використовує Physics.Raycast, хоча існує Physics.BoxCast. В ньому один з параметрів є саме кватерніоном, який дозволяє змінювати кінцевий оберт BoxCast’у.

public static bool BoxCast(Vector3 center, Vector3 halfExtents, Vector3 direction, Quaternion orientation = Quaternion.identity, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);

«Нарешті, не дуже часте, але дуже практичне використання — обертання матриць об’єктів. Так, якщо ви використовуєте GL (низкорівневий класс для малювання) чи Gizmo для того щоб відобразити оберт, то вам доведеться використати кватерніони».
Matrix4x4 rotationMatrix = Matrix4x4.TRS(transform.position, transform.rotation, transform.lossyScale);
Gizmos.matrix = rotationMatrix;
 
Gizmos.DrawCube(...);


Якщо ж казати безпосередньо про обертання предметів, то тут багато прикладів зводяться саме до того, з чим у Гамільтона були проблеми. Тобто, до множення кватерніонів. Зазначимо, що замінити цю операцію можна ейлеровими кутами — іншим метод опису обертання точки.
object.eulerAngles.x += myAngle

Рядочок вище описує поворот об’єкта на кут myAngle навколо осі X. Але в такому випадку результат може бути дивним, оскільки об’єкт може бути вже повернутим по інших осях. Так стається тому, що обертання осі X застосовується до обертання осі Y, але після обертання осі Z. Щоб уникнути цієї плутанини можна використати множення кватерніонів:

object.rotation = Quaternion.AngleAxis(myAngle, Vector3.right) * object.rotation

У цьому випадку ми починаємо з позицій обертання, які вже існують. Вже потім застосовується нове обертання і тепер воно завжди відбуватиметься навколо глобальної осі X.


Також можна згадати метод LookRotation з Unity. Він створює обертання за визначеними напрямками. Наприклад, нам потрібно, щоб камера повільно поверталася до гравця. Спочатку потрібно використати LookRotation для визначення потрібного обертання, а потім метод Slerp (сферичну інтерполяцію між кватерніонами) — він буде зміщувати поточне обертання в кожному кадрі.

void Update()
{
  var towardsPlayer = player.position - camera.position;
  var desiredRotation = Quaternion.LookRotation(towardsPlayer, Vector3.up);
  var currentRotation = camera.rotation;
  var updatedRotation = Quaternion.Slerp(
    currentRotation,
    desiredRotation, 
    rotationSpeed * Time.deltaTime);
  camera.rotation = updatedRotation;
}

Останнім прикладом наведемо метод Quaternion.Euler. З його допомогою можна здійснити поворот на задану кількість градусів навколо осі Z, X та Y в певній послідновності:

using UnityEngine;

public class Example : MonoBehaviour
{
    void Start()
    {
        // A rotation 30 degrees around the y-axis
        Quaternion rotation = Quaternion.Euler(0, 30, 0);
    }
}

У підсумку зазначимо, що хоч кватерніони бувають складні для розуміння, вони дають кілька переваг у порівнянні з використанням інших інструментів для опису обертань. Наприклад, конкатенація (з’єднання) обертання за допомогою кватерніонів відбувається швидше, ніж при використанні матричної форми. А перетворення кватерніонів на матриці відбувається швидше, ніж для кутів Ейлера. У більшості випадків кватерніони вимагають лише чотири числа для представлення обертання, в той час коли матриця вимагає хоча б 9 значень.

Детальніше з документацією для Unity по використанню чотиривимірних гіперкомплексних чисел можна ознайомитися за цим посиланням. А чи використовуєте ви у своїй роботі кватерніони? Яким чином? Можливо, існують більш неочевидні варіанти їх застосування? Діліться в коментарях! Окрім того, якщо ви використовуєте інші математичні об’єкти чи концепції для створення ігор — можете пройти наше невеличке опитування про математику в розробці ігор.

Підписуйтеся на Telegram-канал @gamedev_dou, щоб не пропустити найважливіші статті і новини

👍ПодобаєтьсяСподобалось13
До обраногоВ обраному7
LinkedIn

Схожі статті



Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Використання Quaternion в Unity

👍 Якраз пару днів назад розпитував чат GPT про кватерніони

Тоді в нагоді може стати наш топік)
gamedev.dou.ua/forums/topic/42271

Я ніколи не займався ігровою 3-вимірною графікою, але знаю, що вивчати математику через історію математики значно цікавіше. Без історії і історій реальних людей вона виглядає як якісь сухі тези, які незрозуміло де взялись (хоча і цілком придатні в інженерній практиці). За лаконічними мудрими формулами стоїть титанічна праця і, подекуди, драматичні історії. Ми бачимо еволюцію, прогрес, багато чого стає на свої місця в голові. Про це є цікава книга «Клайн Морис — Математика. Поиск истины» — те з чого я починав. Вона мені була цікава тим, що там детально розглядається історія появи неевклідової геометрії.

Якраз пару днів назад дивився відео на ютюбі про кватерніони, намагаючись зрозуміти їх. А тут якраз стаття, оце так співпадіння. Обовʼязково почитаю, дякую)

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

Слава богу, що той опублікував працю. Хоч і секретну. Ось так би помер той математик, і ми б ще 200 років жили без квартерніонів :))

Підписатись на коментарі