Комментарии 85
Может, вообще стоило начать с тензоров и матриц? А кватернионы рассматривать уже как оптимизацию, позволяющую описывать только повороты и масштабирование?
А, к примеру, углы Эйлера — три числа, без избыточности, но неудобны.
Мне лично матрицы поворота более понятны, их и использую.
Только интерполировать их всё равно нужно через кватернион.
То, что описано в статье, математики зовут «алгеброй Клиффорда». Она определяется следующим набором аксиом:
- Aссоциативноcть: $$(AB)C = A(BC)$$
- Дистрибутивность:
$$A(B + C) = AB + AC \qquad (A + B)C = AC + BC$$ - Умножение на число: $$(αA)B = A(αB) = α(AB)$$
- Умножение на единицу: $$1A = A1 = A$$
- Квардрат вектора: $$aa = a^2 \in \mathbb R$$
Может, вообще стоило начать с тензоров и матриц?
Не может. Алгебра Клиффорда намного более простой и удобный инструмент для подобных вещей.
У меня в черновиках есть статья об алгебре Клиффорда, вдохновлённая книгой «Geometric Algebra for Physicists». Надо бы её наконец дописать и выложить на хабр.
Допишите, допишите.
А кватернионы — часом не частный случай алгебры Клиффорда?
Ну и насчёт удобства — по мне, так для представления поворотов следует разделять абстракцию (для меня это — тензор поворота) и реализацию (матрица, кватернион, ещё что) — чтобы о реализации думать, только когда оптимизируешь программу.
А кватернионы — часом не частный случай алгебры Клиффорда?
Именно так.
Не совсем так. С точки зрения алгебры Клиффорда в таблице умножения кватернионов есть неточность, а именно ijk = 1, а не -1. :). Говорят, Гамильтон налажал :).
Это уже не гиперкомплексные числа получаются. С такими и поле может не получиться.
Я не уверен, что алгебра Клиффорда даёт поле… но оператор антипроизведения, который чем-то похож на деление, некоторые авторы вводят.
Вообще, что до ijk, говорят, что кватернионы получаются, если инвертировать в алгебре клиффорда одно из направлений. Условно, перейти из правой тройки в левую.
ij=-k
jk=-i
ki=-j
Здесь часть с бивектором соответствует «мнимой» части комплексного числа. Только это не «мнимое» значение, это просто бивектор, который мы по-настоящему можем показать графически!
Вообще-то кватернион — это вектор в четырехмерном пространстве. Его базис [1, i, j, k] образует группу
Кроме этого, группа кватернионов (как и комплексных чисел) естественным образом порождает метрику Евклида
Кроме этого, кватернион имеет естественное представление в виде матрицы 4 x 4
Если вас смущает название «мнимая часть», то существует альтернативное название — «векторная часть». Если мы работаете в трехмерном пространстве, то существует бесчисленное множество способов его получить из четырехмерного (хотя бы взять скалярную часть равной нулю)
Главное различие в том, что… заменяются на…, но работают они в основном так же
Вы сделали следующее — отбросили скалярную часть (приравняли к нулю) и ввели переобозначение
Кватернион и комплексные числа, — уникальные математические объекты. Их действия (q1 * q2) есть суть преобразования евклидова четырехмерного и двухмерного пространств. Отношения между базисными элементами составляют, если хотите, таблицу логики пространства (плоскости)
А зачем видеть «ось вращения» кватерниона/матрицы? Обычно нужно обратное преобразование: дай мне хреновину, которую можно применить к куче векторов, чтобы повернуть их на такой-то угол.
Это более общее решение чем кватернионы и не имеющее проблем с двойным покрытием, но считается оно дольше
v23 := P15.DotProduct(p21) * -2.0 + P15.DotProduct(P15) + p21.DotProduct(p21) - Radius * Radius;
v24 := (P18.Z-P15.Z) * (P18.Z-P15.Z) + (P18.X-P15.X) * (P18.X-P15.X) + (P18.Y-P15.Y) * (P18.Y-P15.Y);
v25 := (P15.X-p21.X) * (P18.X-P15.X) + (P15.Y-p21.Y) * (P18.Y-P15.Y);
v26 := (P15.Z-p21.Z) * (P18.Z-P15.Z) + v25 +(P15.Z-p21.Z) * (P18.Z-P15.Z) + v25;
v27 := v26 * v26 - 4.0 * v24 * v23;
v23 := P15.DotProduct(p21) * -2.0 + P15.DotProduct(P15) + p21.DotProduct(p21) - Radius * Radius;
_P18 := P18 - P15;
_P15 := P15 - p21;
v26 := _P15.DotProduct(_P18);
v27 := ( v26 * v26 - _P18.DotProduct(_P18) * v23 ) * 4.0;
Полная функция:
function TWarpData.RaySphere(var a1, a2: Double; Radius: Double; P15, P18, p21: TPoint3D): Boolean;
var
v23, v24, v25, v26, v27, v29, v30, v31: Double;
begin
Result := false;
v23 := P15.DotProduct(p21) * -2.0 + P15.DotProduct(P15) + p21.DotProduct(p21) - Radius * Radius;
v24 := (P18.Z - P15.Z) * (P18.Z - P15.Z) + (P18.X - P15.X) * (P18.X - P15.X) + (P18.Y - P15.Y) * (P18.Y - P15.Y);
v25 := (P15.X - p21.X) * (P18.X - P15.X) + (P15.Y - p21.Y) * (P18.Y - P15.Y);
v26 := (P15.Z - p21.Z) * (P18.Z - P15.Z) + v25 + (P15.Z - p21.Z) * (P18.Z - P15.Z) + v25;
v27 := v26 * v26 - 4.0 * v24 * v23;
if (v24 >= 0.0) then
begin
if (v24 < 0.00001) then
begin
a1 := 0;
a2 := 0;
Result := false;
Exit;
end;
end
else if (v24 > -0.00001) then
begin
a1 := 0;
a2 := 0;
Result := false;
Exit;
end;
if (v27 >= 0.0) then
begin
v30 := sqrt(v27);
v31 := v24 + v24;
a1 := (v30 - v26) / v31;
v29 := (-v26 - v30) / v31;
Result := true;
end;
a2 := v29;
end;
Единственных два условия которые здесь имеют смысл это:
if (v24 < 0.00001) then
if (v27 >= 0.0) then
Потому что v24 не может быть меньше нуля. А v27 это проверка на пересечение луча со сферой. Хотя технически первое тоже имеет малое значение — случай когда точка луча находиться в центре сферы.
v23 := P15.DotProduct(P21) * -2.0 + P15.DotProduct(P15) + P21.DotProduct(P21) - Radius * Radius;
P18 := P18 - P15;
v24 := P18.DotProduct(P18);
P15 := P15 - P21;
V26 := P15.DotProduct(P18) * 2;
v27 := v26 * v26 - 4.0 * v24 * v23;
Да и собственно, как вы сказали, название коэффициентов тут не критично.
зы Жаль карма нулевая… Ну и тысяча извинений, человек не был рожден ни математиком, ни программистом, он бы рождён реверсером. *грустный смайлик*
А под спойлером написан совершенно бессмысленный вывод для x(xy), где сначала используется формула xy = x ∙ y + x ∧ y, а потом x ∧ y заменяется обратно на xy.
И да, совершенно не понятны претензии к приравниванию длины вектора к площади параллелограмма в статье, в которой дальше безо всяких объяснений вектор умножается на параллелограмм два раза, а потом результат снова приравнивается к вектору :-)
gen.lib.rus.ec/search.php?req=lounesto+clifford+algebras+and+spinors&open=0&res=25&view=simple&phrase=1&column=def
и по-русски есть книжечка (проще, но меньше и сумбурнее)
gen.lib.rus.ec/search.php?req=казанова+от+алгебры+клиффорда&open=0&res=25&view=simple&phrase=1&column=def
И в более высоких измерениях (4D и выше) невозможно определить один вектор нормали к 2D-плоскости (например, в 4D у 2D-плоскости есть два направления нормалей, в 5D есть три направления нормалей)
Другими словами, на плоскости возможен поворот вокруг точки, в 3D пространстве — относительно прямой, в 4D пространстве — относительно плоскости, а в nD пространстве — относительно объекта размерности n - 2
. Матрицы поворота вокруг точки и оси хорошо известны: Rotation matrix, Rodrigues' Rotation Formula. Однако матрицы поворота вокруг плоскости и объектов более высоких размерностей тоже выводятся. В 2012 задавался этим вопросом на math.stackexchange.com.
Ну и как вы сделаете поворот в плоскости не указав центра, только с углом и той самой плоскостью?
Поворот всегда выполняется вокруг начала координат. Поворот вокруг любой другой точки является композицией поворота и сдвига.
Так всё-таки, поворот всегда выполняется вокруг начала координат или бывают повороты и вокруг других точек?
Поворот в смысле "линейного оператора" действительно выполняется вокруг начала координат, но "сдвиг" не является линейным оператором и комбинировать их нельзя. А поворот в смысле "движения пространства" который может комбинироваться со "сдвигом" не обязательно выполняется вокруг 0. Любой поворот может быть представлен в виде поворота вокруг 0 и сдвига но понятие "поворот вокруг оси" / "заданной точки" совершенно нормально а "ось" в виде подпространства точки которого оператор поворота переводит в себя определена в таком случае лучше чем ортогональная ей "плоскость вращения".
Что до того, кто лучше определён, то тут конечно, кому что больше нравится, но статья посвящена геометрической алгебре. Ротор это сумма скаляра и бивектора, то есть, скаляра и объекта отвечающего в ГА за плоские характеристики. Прелесть этого объекта в том, что в пространстве любой мерности он останется именно суммой скаляра и бивекторов. В нем будут появляться новые компоненты, потому как пар осей будет становиться больше, больше и больше. Кстати, количество элементарных поворотов равно количеству пар осей, что как бы намекает.
И да, у меня старший брат боксёр, а еще я тебя по айпи вычислю.
Опечатка “является улучшенной версией скалярного тройного произведения”, у нас в литературе это называется смешанным произведением.
Мой дилетантский взгляд такой. Первым делом нужно более корректно сформулировать проблему без «сложно/непонятно/не хочу вникать»:
1) в 2D-плоскости вращение можно описать через умножение комплексных чисел, при этом мы получаем в наследство всю мощь классического и комплексного анализа;
2) в 3D-пространстве появляются 4 степени свободы для вращения и очевидно что в 3 координаты они не влезут. Поэтому таки приходится привлекать кватернионы.
3) но у кватернионов другая проблема — 4 координаты избыточны для положения, плюс у них некомутативность по умножению, что довольно неудобно в аналитических вычислениях. Ну и двойное покрытие конечно же. Ну и глядя непосредственно на компоненты кватерниона сложно сходу сказать, относится он к координатам, повороту или чему-то ещё (ну может в него CMYK закодировали, мало ли).
Кватернион в терминах линейной алгебры можно рассмотреть как композицию скалярной части и векторной части. По аналогии можно определить 5D-объект из комплексной части и векторной части (2D-ротор и 3D-положение). Таким образом, можно определить умножение, в котором векторная часть вообще не будет задействована (в случае нормализованного ротора). Правда, коммутативность таким образом обеспечить скорее всего не получится. Но зато коммутативность получится обеспечить через тип комплекс-комплекс, где компоненты комплексного числа тоже комплексные числа (идея тоже не новая, и в первых экспериментах пока всё сходится с интересными нюансами. Собственно, на эту статью я и набрёл в поисках готового решения, чтобы не изобретать велосипед без необходимости).
Математически это значит что мы работаем с выражением
(a+b·i)+(c+d·i)·j
, где скобки не раскрываются а мнимые единицы не перемножаются. Итого имеем 4 числа, но только две мнимых единицы.Потому комплексные числа коммутативны, а кватернионы — нет.
Это напрямую следует из того, что в Cl(2,0,0) есть всего одна пара ортов, а в Cl(3,0,0) их уже три.
Подождите, уважаемые! Какие 4 степени свободы для вращения в 3D? Часто говорят о трех степенях свободы вращения: углы Эйлера, углы Крылова, единичный вектор задающий ось (2 степени свободы) + угол (еще одна степень). Если с такой точки зрения посмотреть, то единичный кватернион, на самом деле трехмерный, потому что мы любую его компоненту можем выразить через 3 другие.
Но на самом деле нам просто удобно считать повороты трехмерными в трехмерном пространстве. На самом деле они двумерные:) Любой поворот можно описать двумя скалярными значениями!
И чтобы понять двумерность кватерниона, представьте его в таком виде:
А что касается некоммутативность произведения кватернионов - то это отражение некоммутативность поворотов, любое адекватное описание поворотов будет некоммутативным :)
4 степени свободы в 3D это: 3 координаты в пространстве плюс состояние поворота вектора вокруг своей оси.
Для задания оси в 3D пространстве достаточно 2х координат. Один из классических способов - берем половинку сферы и проецируем ее на плоскость по которой она была обрезана. Любой оси соответствует единственная точка пересечения с этой полусферой а любой точке полусферы - единственная точка на этой плоской проекции. Третья координата нужна для указания поворота относительно этой оси, да.
Да, в 3D ось можно задать 2мя параметрами. Еще вариант, если лень резать сферу, вспомнить, что длина оси должна. быть единичной. Тогда любую компоненту оси можно найти из двух других (но возникает вопрос с ее знаком) + угол поворота. Более однозначный вариант - задать поворот не единичной осью, а вектором, длина которого соответствует углу поворота в радианах. Экспонента этого вектора и будет кватернионом.
А что касается двумерного представления поворота, тут такая штука: мы можем зафиксировать на воображаемой сфере единичного радиуса с центром в начале координат произвольную точку. Ее положение описывается двумя параметрами (например, сферическими координатами без радиуса - он ведь известная константа). Тогда поворот можно определить через вторую точку, в которую перейдет первая при повороте сферы. И имеем преобразование в двумерном пространстве => поворот двумерен.
Как между собой помирить эти две концепции? Очень просто. В двумерном преставлении каждый поворот можно получить в виде композиции поворотов вокруг 2х осей (например, x и y), назовем их базисными поворотами. Но эти базисные повороты не коммутативные. И для описания каких-то поворотов надо будет сначала выполнить поворот вокруг оси x потом вокруг y, а в других ситуациях - наоборот.
Но в обоих случаях для построения кватерниона поворота нам будет нужно два параметра и , а сам кватернион будет выглядеть как или
Вот и получается, что любой поворот двумерный, но их есть два вида. А введение третьей оси избавляет нас от неоднозначности.
Предлагаю просто не подпускать к 3D движкам тех, кому лень разобраться с кватернионами :)
Печально, что основной аргумент против кватернионов - с ними лень разбираться. Любое описание поворотов в трехмерном пространстве представляет собой группу группу вращений, а значит в некотором смысле эквивалентны. Другое дело, что разные представления вращений могут быть по разному удобны или неудобны, например, с точки зрения сложности вычислений или требуемого количества переменных. Не последнюю роль в этом удобстве играет численная устойчивость.
А еще важную роль играет возможность обобщения. Для кватернионов, например, переход к дуальным бикватернионам позволяет в рамках одной концепции описывать любое движение: и поворот, и параллельный перенос, и поворот вокруг заданного центра поворота. Но это точно не для тех персонажей, которым даже с сутью кватернионов лень разобраться :)
Вы не выкурили суть статьи. ТС предлагает не избавится от кватернионов, а заменить их их же обобщением. И это правильно с теоретической точки зрения, потому что геометрическая алгебра как раз таки отлично обосновывает кватернионы. Впрочем, вычислительно получается тоже самое.
Так себе обобщение. Формулы для сферической интерполяции автор не даёт, и где её брать — совершенно непонятно (особенно учитывая что автор так и не объяснил что за магия произошла в пункте 3.4)
Ну вот проще было бы понять преимущество предлагаемого подхода, если бы автор показал, как из ротора найти ось поворота, как интерполировать роторы, что там с логарифмом ротора и экспонентой вектора вращения и т.д. Половины свойств кватерниона в бивектороном представлении не раскрыта.
А аргумент, что это то же самое, но более понятно предполагает, что должны быть описаны все те же свойства :)
Да, и совсем не понятно, как это обобщить на случай не только поворота вокруг начала координат, а вокруг произвольной точки или на случай параллельного переноса. Вот с бикватернионами я понимаю, как это сделать. А где решение того же самого, согласитесь, совсем не праздного для задач графики вопроса про параллельный перенос и поворот вокруг произвольного центра в представлении роторов?
Тут бы до конца довести рассуждения...
Да, еще хочу ответить на поставленные вопросы:
Почему и ?
по определения, а следует из - что тоже по по определению.
Почему мы берём вектор и превращаем его в «мнимый» вектор, чтобы преобразовать его, например ?
Потому что сложение вращений - это произведение их кватернионов, значит преобразование из пространства вращений, заданных осями в пространство соответствующих кватернионов - это экспонента . А берем именно комплексные оси, потому что вращение периодичное, как и экспонента комплексного числа.
Да кому это интересно, если всё работает, правда?
Наверное, это интересно тому, кто претендует на то, чтобы позиционировать себя как профессионала, а не как юного студента троешника :)
Спасибо! Вы меня вдохновили: https://habr.com/ru/articles/757750/ :))
Давайте уберём кватернионы из всех 3D-движков