Disclaimer: fundamental math theory may not be 100% accurate
TODO:
- формула проекции
- добавить геометрический смысл объектов и произведений
- добавить геометрическую трактовку RP²
- правильно называть базис/элемент/член e₁e₂ и т.п. ...
- line-reflection, flectors
- формулы расстояний, длин и т.п.
- later: dynamics
PGA2D (Projective Geometric Algebra) обозначается как: $R^*_{2,0,1}$
Содержание:
[1] Теория
Построение алгебры (базис, метрика)
Алгебра строится над пространством.
В качестве исходного пространства используется проективная плоскость, обозначаемая как: $RP^2$. Базис проективной плоскости составляют:
- e₁ и e₂ — «настоящие» (евклидовы) вектора
- e₀ — проективный вектор
Базис проективного пространства: {e₁, e₂, e₀}
- Чтобы построить именно геометрическую алгебру, в пространстве вводится метрика
- Геометрическая алгебра, построенная конкретно над проективной плоскостью, и есть PGA2D
- Элементы геометрической алгебры (в т.ч. и PGA2D) называются мультивекторами
Вводимая метрика для базиса $RP^2$: {+1, +1, 0}
Такая метрика означает, что: e₁e₁ = 1, e₂e₂ = 1, e₀e₀ = 0
Введиние метрики порождает алгебру, базис которой (в случае PGA2D) состоит из 8 элементов.
В моём подходе все формулы выстроены для следующего базиса:
Базис алгебры: {1, e₁, e₂, e₀, e₂₀, e₀₁, e₁₂, e₀₁₂}
Мультивектор : {s, nx, ny, d , px , py , pw , ps }Запись {s, nx, ny, …} обозначает мультивектор [mv = s + nx*e₁ + ny*e₂ + ...]
В других учебных материалах могут брать немного другие базисы:
- может бьть другой порядок базисных векторов, например: {1, e₀, e₁, e₂, ...}
- может быть переставлен порядок векторов в бивекторе/тривекторе: например, за базисный может браться не e₂₀, а e₀₂
Полная таблица перемножения базисных n-векторов:

Геометрическое произведение базисных векторов
Виды мультивекторов (k-vector, k-blade, versor)
Определения, использующиеся во всех видах GA:
- k-Vector — MV, состоящий только из Grade-k элементов
- k-Blade u (simple k-Vector u) — u можно разложить во внешнее произведение k штук 1-векторов: u = v₁ Λ v₂ Λ …
- Versor u — u можно разложить в геометрическое произведение k штук 1-векторов: u = v₁v₂…
- Все 1-векторы являются и блейдами и версорами
- Все блейды являются версорами
Применительно к PGA2D:
- Все E.Lines, I.Lines, E.Points, I.Points являются блейдами и версорами
- Motors в общем случае являются версорами, но не обязательно блейдами
Обоснование:
- E.Lines и I.Lines являются 1-векторами
- E.Points являются внешними произведениями линий: E.Point = E.Line1 Λ E.Line2
- I.Points:
- можно разложить на произведение [px*e₂₀ + py*e₀₁ = e₀(-px*e₂ + py*e₁)]
- исходя из свойств внешней алгебры (для любой GA), для базисных векторов геометрическое произведение заменяется внешним: e₀e₂ = e₀Λe₂ (аналогично для e₀e₁)
- итого, мы успешно разложили I.Point на внешнее произведение 1-векторов
- Motors являются композициями отражений (т.е. геометрическими произведениями 1-векторов)
[2] Формулы для кодинга
Объекты PGA2D
Базисы
Все формулы ниже даются для базисов:
- Базис пространства: {e₁, e₂, e₀}
- Метрика: {+1, +1, 0 }
- Базис алгебры: {1, e₁, e₂, e₀, e₂₀, e₀₁, e₁₂, e₀₁₂}
- Мультивектор : {s, nx, ny, d , px , py , pw , ps }
Объекты
Объекты алгебры PGA2D:
Объект | Координатная форма | Требования |
---|---|---|
Scalar | {s, 0 , 0 , 0, 0 , 0 , 0 , 0 } | |
Pseudoscalar | {0, 0 , 0 , 0, 0 , 0 , 0 , ps} | ps ≠ 0 |
E.Line : nx*x + ny*y + d = 0 | {0, nx, ny, d, 0 , 0 , 0 , 0 } | nx² + ny² ≠ 0 |
I.Line (line at infinity) | {0, 0 , 0 , d, 0 , 0 , 0 , 0 } | d ≠ 0 |
E.Point: {px/pw, py/pw} | {0, 0 , 0 , 0, px, py, pw, 0 } | pw ≠ 0 |
I.Point (direction): {px, py} | {0, 0 , 0 , 0, px, py, 0 , 0 } | px² + py² ≠ 0 |
Motor: Rotator | {s, 0 , 0 , 0, px, py, pw, 0 } | pw ≠ 0 |
Motor: Translator | {s, 0 , 0 , 0, px, py, 0 , 0 } |
(E = Euclidean, I = Ideal)
Полезно ввести константы:
Объект | Координатная форма |
---|---|
US (Unit Scalar) | {1, 0 , 0 , 0, 0 , 0 , 0 , 0 } |
UPS (Unit Pseudoscalar) | {0, 0 , 0 , 0, 0 , 0 , 0 , 1 } |
(US обозначает простой скаляр, но подчёркивает, что этот скаляр — часть алгебры)
Произведения 2х векторов
[Info] Общие замечания к трактовке кода
Мультивекторы в формулах записываются в виде списков из 8 элементов:
mv = {s , nx , ny , d , px , py , pw , ps } ;
mv1 = {s1, nx1, ny1, d1, px1, py1, pw1, ps1} ;
mv2 = {s2, nx2, ny2, d2, px2, py2, pw2, ps2} ;
В формулах для произведений предполагаются:
- входные вектора: mv1, mv2
- результирующий вектор: mv
При перемножении нескольких векторов, например a Λ b Λ c :
- Порядок векторов — важен, т.к. их перестановка меняет результат
- Эти замечания работают для всех приводимых ниже видов произведений
Geometric Product (juxta)
Формула выводится напрямую из метрики:
- По определению GP:
- eiej = —ejei
- eiei = 0
- По метрике: e1e1 = +1, e2e2 = +1, e0e0 = 0
Далее просто подставляем и группируем:
(s1 + nx1∗e1 + ..)(s2 + nx2∗e2 + ..) =
(s1∗s2) + nx1∗s2∗(e1) + nx2∗s1∗(e2) + nx1∗nx2∗(e1e2) + ...
|
|
GP ассоциативно, т.е. (ab)c = a(bc)
Outer Product (Λ, meet)
Используется определение внешнего произведения на n-векторах a и b:
- $a \land b = \langle ab \rangle_{s+t}$
- здесь: Grade[a] = s, Grade[b] = t
Эта формула далее просто напрямую расширяется на произвольный мультивектор. И проводится общее суммирование по грейдам.
При этом если s+t ≥ 4
, то произведение считается равным нулю.
|
|
OP ассоциативно, т.е. (a Λ b) Λ c = a Λ (b Λ c)
Inner Product
Используется определение внутреннего произведения на n-векторах:
- $a \land b = \langle ab \rangle_{|s-t|}$
- здесь: Grade[a] = s, Grade[b] = t
Аналогично OP, эта формула далее расширяется на произвольный мультивектор.
|
|
IP не ассоциативно, т.е. (a·b)·c ≠ a·(b·c)
Regressive Product (V, join)
Для произвольных мультивекторов a и b:
- $a \lor b = (a^{\ast} \land b^{\ast})^{\ast}$
- «*» здесь обозначает дуализацию (см. Dual)
|
|
RP ассоциативно, т.е. (a V b) V c = a V (b V c)
Sandwich Product
Определение сэндвич-произведения для произвольных МВ:
WP[a, b] = bab~
(здесь «a~» это Reverse a, см. ниже)
Как следствие, для композиции моторов:
WP[a, m₂m₁] = m₂m₁am₁~m₂~
Вычислительно, рекомендую реализовывать функцию WP в виде: WP[a, {b1, b2, …}], где bi — список произвольной длины
Преобразования одного вектора
Grade projection
Операция Grade projection просто берёт от МВ соответствующий грейд, зануляя остальные элементы.
Обозначается угловыми скобками. Например, обозначение Grade-2 проекции: $ \langle a \rangle_{2}$
|
|
Dual (*)
У дуальности довольно сложное геометрическое определение, поэтому не привожу его здесь. Скажу только, что формула ниже выводится из определения дуальности, без каких-то промежуточных формул.
|
|
Reverse (~)
Реверс по определению «переворачивает» порядок произведения базисных векторов.
Например: (e₀e₁e₂)~ = e₂e₁e₀ = -e₂e₀e₁ = e₀e₂e₁ = -e₀e₁e₂
И аналогично для всех базисных элементов.
Конкретно для PGA2D, реверс просто меняет знак 2- и 3-грейд составляющих мультивектора.
|
|
Polar (⊥)
По определению, для произвольного мультивектора a:
- $a^{\perp} = GP[a, UPS]$
- Словами: полярный мультивектор суть геометрическое произведение исходного мультивектора на Unit Pseudoscalar
- UPS = {0, 0, 0, 0, 0, 0, 0, 1}
|
|
В частности, поляризация E.Line порождает I.Point (Direction):
|
|
Вычисления норм мультивектора
[Info] Норму вычисляют только для версоров
Про версоры:
- Версор — МВ, представимый в виде геом.произведения 1-векторов
- В PGA2D версорами являются: E.Line, I.Line, E.Point, I.Point, Motors
Вычисление нормы опирается на вычисление GP[mv~,mv]:
|
|
Для указанных выше версоров GP[mv~,mv] имеет только скалярную составляющую, поэтому для версоров используют формулу $\langle GP[\tilde{vrsr}, vrsr] \rangle _{0}$ :
|
|
Inverse (⁻¹)
Обратный мультивектор по определению: GP[a, a⁻¹] = 1
Известна формула для версоров:
a⁻¹ = a~/GP[a~,a]
|
|
(здесь заложено, что Norm тоже работает только на версорах)
Norm (Bulk)
Строгое определение для произвольного МВ a:
$Norm[a] = \sqrt{GP[a, \tilde{a}]}$
Для версоров GP[a,a~] имеет только скалярную составляющую, т.е. для них
можно использовать формулу:
$Norm[a] = \sqrt{\langle GP[a, \tilde{a}] \rangle _{0}}$
|
|
Следствия:
- Norm[E.Line ] = Sqrt[nx² + ny²]
- Norm[E.Point] = |pw|
- Norm[I.Line ] = 0
- Norm[I.Point] = 0
- Norm[Rotator] = Sqrt[s² + pw²]
- Norm[Translator] = |s|
Ideal Norm (Weight, Infinity Norm)
Строгое определение для произвольного МВ a:
$INorm[a] = \sqrt{GP[a^{\ast}, \tilde{a^{\ast}}]}$
Для версоров GP[a*,(a*)~] имеет только скалярную составляющую, т.е. для них:
|
|
Normalize
По определению, нормированный мультивектор удовлетворяет условию:
GP[a,a~] = 1
Поэтому, для версоров с Norm[a] ≠ 0 (т.е. для E.Point, E.Line и Motors):
|
|
Для I.Point и I.Line вводится идеальная нормализация:
|
|
Моторы
[Info] Вычисление и применение моторов
Моторы вычисляются как экспоненты 2-векторов, для чего используется формула:
Exp[mv] = 1 + mv/1! + mv²/2! + mv³/3! + ...
(здесь возведение в степень — это геометрическое произведение вектора на себя)А уж почему эспоненцирование 2-вектора является мотором — вопрос отдельный...
Формулы применения моторов (juxta означает GP):
- Композиция моторов m₁ и m₂:
- Для нормированных/ненормированных моторов:
m₂m₁
- Если исходные моторы нормированные, то и результирующий будет нормированным
- Применить мотор m к объекту A:
mAm~
- Ненормированный мотор может менять норму/ид-норму A (проверить)
- Ненормированный объект может менять норму/ид-норму при действии нормированных моторов (проверить)
В PGA2D существуют только 2 вида моторов (если не касаться флекторов): ротаторы и трансляторы. В общем случае композицией ротатора и транслятора является ротатор вокруг новой точки.
Смена знака всех элементов мотора не влияет на его действие
Rotators as Exponent
Ротатор на угол α вокруг нормированной E.Point NEP:
- NEP = {0, 0, 0, 0, px, py, 1, 0}, при этом д/б √(px² + py²) ≠ 0
- Rotator = Exp[α*NEP/2] = Cos[α/2] + Sin[α/2]*NEP
- Получившийся ротатор будет нормированным
Для ненормированной E.Point EP:
|
|
Translators as Exponent
Транслятор на расстояние dist перпендикулярно ид-нормированной ид-точке I.Point INIP:
- INIP = {0, 0, 0, 0, px, py, 0, 0}, при этом √(px² + py²) = 1
- Exp[dist*INIP/2] = 1 + dist*INIP/2
- Получившийся транслятор будет нормированным
Для не-ид-нормированной ид-точки I.Point IP:
|
|
Кстати, I.Point можно получить через поляризацию E.Line или I.Line:
- Polar[{0, nx, ny, d, 0, 0, 0, 0}] = {0, 0, 0, 0, nx, ny, 0, 0}
- Нормированная E.Line породит ид-нормированную I.Point
- Ид-нормированная I.Line породит ид-нормированную I.Point
Deconstructing Translator
Деконструирование восстанавливает dist и ид-нормированную I.Point:
{0, 0, 0, 0, px, py, 0, 0}
Вывод формулы сделаем для общего случая ненормированного транслятора:
- Normed translator:
{1, 0, 0, 0, dist/2\*px, dist/2\*py, 0, 0}
- Non-normed translator:
{A, 0, 0, 0, X, Y, 0, 0}
Деконструирование:
- В общем случае tr :=
{A, 0, 0, 0, X, Y, 0, 0}
- Если A<0, то просто работаем с tr := -1*tr
- Надо разрешить 3 уравнения:
- X/A = px*dist/2
- Y/A = py*dist/2
- √(px² + py²) = 1
В итоге получаем:
- dist = 2*√((X/A)² + (Y/A)²)
- px = 2*(X/A)/dist
- py = 2*(Y/A)/dist
Deconstructing Rotator
Деконструирование восстанавливает угол поворота alpha и нормированную E.Point:
{0, 0, 0, 0, px, py, 1, 0}
Вывод формулы сделаем для общего случая ненормированного ротатора:
- Normed rotator:
{Cos[α/2], 0, 0, 0, px*Sin[α/2], py*Sin[α/2], Sin[α/2], 0}
- Non-normed rotator:
{C, 0, 0, 0, X, Y, S, 0}
Деконструирование:
- В общем случае rot := {C, 0, 0, 0, X, Y, S, 0}
- Надо разрешить 3 уравнения:
- cc = Cos[α/2] = C/√(C² + S²)
- ss = Sin[α/2] = S/√(C² + S²)
- px*Sin[α/2] = X/√(C² + S²)
- py*Sin[α/2] = Y/√(C² + S²)
В итоге получаем:
- Первые 2 уравнения содержат достаточно информации для извлечения α ∈ (-π,π] (например, в Python можно использовать α = 2*math.atan2(ss, cc))
- px = X/S
- py = Y/S
Переходы моторов в другие объекты
Ротатор {Cos[α/2], 0, 0, 0, px*Sin[α/2], py*Sin[α/2], Sin[α/2], 0}
:
- При alpha = 0 ротатор переходит в Scalar
- При alpha = ±π ротатор переходит в E.Point
Транслятор {1, 0, 0, 0, dist/2*px, dist/2*py, 0, 0}
:
- При dist = 0 транслятор переходит в Scalar
Motors from geometry
Пусть A и B — либо 2 E.Point, либо 2 E.Line.
Чтобы перевести A в B надо приложить мотор motor
:
- B = WP[A, motor]
- motor = √(B/A) = Sqrt[GP[B, Inverse[A]]