Разделить кватернион 1 и кватернион 2 друг от друга на количество градусов? - PullRequest
0 голосов
/ 28 марта 2020

Как я могу отделить кватернион 1 и кватернион 2 друг от друга по количеству градусов?

<--q1q2--> to <--q1---q2-->

Я пробовал slerp с интерполированным значением 1,1 - это правильное направление. Но мне нужно обновить кватернионы на фиксированное установленное значение. В противном случае расстояние между q1 и q2 увеличивается экспоненциально между каждым обновлением.

Редактировать: Если смотреть на него по одной оси: Q1<-20°->Q2 после каким-то образом изменение Q2 - он идет или становится Q3, упомянутым в ответе: Q1<-30°->Q2orQ3, когда требуется отделить один из задействованных кватернионов на 10 °. Обратите внимание, что это должно быть в правильном направлении, указанном выше.

Моя проблема может быть описана как попытка добавить физику столкновений к игровым объектам, которые вращаются вокруг пользователя - чтобы они не перекрывали друг друга и не перекрывали каждый Другой. В то же время, как можно меньше удаляясь от своей исходной позиции.

Мне нужно, чтобы игровые объекты находились в одном и том же повороте от пользователя, чтобы прекратить укладку - и вместо этого образовывать кластеры. Так что каждый объект можно увидеть и взаимодействовать с ним.

Я использую System.Numerics C# Quaternion

Ответы [ 2 ]

0 голосов
/ 09 апреля 2020
void Apart(Quaternion q1, Quaternion q2)
{
    var angle = Calc.ToRad(0.4f);
    var vector = new Vector3(1, 1, 0); // new Vector(1, 1, 1) if 3d probably!
    someObj1.Orientation = q1 * Quaternion.CreateFromAxisAngle(vector, angle);
    someObj2.Orientation = q2 * Quaternion.CreateFromAxisAngle(vector, -angle);
}

Это приводит к тому, что сложенные объекты анимируются друг от друга - в моем мобильном приложении создается диагональная линия объектов, которая визуализирует объекты, заданные их Orientation на экране в 2D.

Таким образом, разделение только в одна ось: var vector = new Vector3(0, 1, 0); означает: <OO> . <O-O> .. <O--O> при каждом обновлении


Редактировать :

Фактически vector пришлось разложить и умножить угол на все оси отдельно.

// where UnitX is (1, 0, 0) and UnitY (0, 1, 0)
someObj1.Orientation = q1 * Quaternion.CreateFromAxisAngle(Vector3.UnitX, xAngle) * Quaternion.CreateFromAxisAngle(Vector3.UnitY, yAngle); 
someObj2.Orientation = q2 * Quaternion.CreateFromAxisAngle(Vector3.UnitX, -xAngle) * Quaternion.CreateFromAxisAngle(Vector3.UnitY, -yAngle);

Поскольку мне нужно было разделиться с указанным c углом, а в 2D я мог просто взять проценты от этого угла:

var angle = Calc.ToRad(0.4f);
var makePortions = new Random().NextDouble();
var xAngle = (float)(angle * makePortions);
var yAngle = (float)(angle * (1 - makePortions));

В противном случае изменение угла по оси X перестанет действовать на ориентацию объектов в пределах 180 градусов по оси Y.

0 голосов
/ 03 апреля 2020

Я думаю, что это то, что вы хотите:
0) говорят, что у вас есть Q1 и Q2, и вы хотите, чтобы Q3 10 градусов от Q1 к Q2:
1) получить угол между Q1 и Q2.
2 ) Q3.w = Q1.w * cos (10 градусов) / cos (угол)
3) Q3.x = Q1.x * sin (10 градусов) / sin (угол)
4) то же самое для Q3.y и Q3.z.

Вы должны проверить Q1 = Q2.

Я могу добавить javascript (используя библиотеку 3. js), если хотите.

...