Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Кватернионы: извлечение вращения вдоль одной из осей

Кватернионы: извлечение вращения вдоль одной из осей

Поделиться

Страницы: 1 2 Следующая

AlerrПостоялецwww5 окт. 201719:17#0
Привет всем!
Имеется тело с текущим вращением (RotA) и конечным вращением (RotB).
Нужно найти вращение (кватернион RotX), который бы удовлетворял...

<—Сообщение исправлено—>
Изначальнейшая формулировка задачи такая:
Есть 2 тела: redCibe и whiteCube.
1) redCibe вращается сразу по всем осям и нам известно его rotation. Он лежит в мире и игрок не может с ним взаимодействовать (брать его).
2) Rotation whiteCube тоже известно. Игрок может его брать и таскать.

В зависимости от того какая из осей выбрана игроком (ox/oy/oz) - это локальные оси игрока, по выбраной из осей whiteCube должен быть повернут так же как и redCube.
Например вот 2 куба, whiteCube не взят, redCube повернут по 2-м  осям и лежит в мире рис1:

+ Показать

Теперь игрок выбирает ось OY (на картинках это ось вверх) и берет whiteCube => whiteCube по OY повторяет redCube рис2:

+ Показать

Мне удалось найти вращение rotX, которое удовлетворяет:

redCubeRot = whiteCubeRot * rotX;
Но rotX переводит вращение whiteCube во вращение redCube без учета осей, то есть в итоге redCubeRot равно whiteCubeRot.
Нужно найти такое вращение rotX, которое возволяет повернуть whiteCube по одной из осей (рис1 -> рис2).
Как найти такое вращение?

Правка: 7 окт. 2017 9:56

SuslikМодераторwww6 окт. 20175:41#1
Alerr
очевидно, ответ на вопрос "как вычленить поворот только по одной оси из кватерниона" будет содержаться в определении понятия "вычленить поворот только по одной оси", так как ты его придумал сам и какой смысл в него вложил, известно только тебе. например, можно обнулить все компоненты кватерина кроме нужной тебе координатной оси и перенормализовать w-компоненту. ещё можно перейти в плоскость, перпендикулярную интересующей тебя оси и построить кватернион в ней. но наиболее конструктивно, вероятно, будет объяснить, чего ты патешься этими манипуляциями добиться, тогда уже можно будет сказать, как это лучше сделать.
PA3UJIbПостоялецwww6 окт. 20177:33#2
Может, если RotA это исходное вращение, а RotB новое вращение, то следует писать
Quaternion rotX =  Quaternion.Inverse(cubeRigidBody.rotation) * newRotation;
нет?
AlerrПостоялецwww6 окт. 201711:11#3
Suslik
Есть 2 куба: серый и красный:
+ Показать

Серый куб - это тот, что нужно вращать по оси OY.
Вращение серого куба по OY должно быть таким же как и вращение красного ТОЛЬКО по OY:
+ Показать

Да, еще условие: найденное RotX используется в других частях кода, потому нужно найти меннно RotX по одной из осей чтобы:
RotA * RotX = RotB.
> можно обнулить все компоненты кватерина кроме нужной тебе координатной оси и перенормализовать w-компоненту.
На сколько понимаю, этот вариант не подходит так как мне не известен угол поворота, известны только кватернионы RotA и RotB.
Вроде понятно изложил задачу.

PA3UJIb
проверил, спасибо, вы правы, но основная проблема все же не в этом.

Правка: 7 окт. 2017 11:07

AlerrПостоялецwww6 окт. 201715:53#4
Есть общая формула получения кватерниона:
void createQuat(Vector3 rotate_vector, float rotate_angle) {
    Quaternion create_quat;
    Vector3 rotate_vector = normal(rotate_vector);
    create_quat.w = Cos(rotate_angle / 2f);
    create_quat.x = rotate_vector.x * Sin(rotate_angle / 2f);
    create_quat.y = rotate_vector.y * Sin(rotate_angle / 2f);
    create_quat.z = rotate_vector.z * Sin(rotate_angle / 2f);
}
У меня есть вращение сразу по нескольким осям RotX.
Пробую выделить из этого вращения угол вращения только по одной из осей вот так:
void recalculateStartRot() {
    Quaternion rotX = Quaternion.Inverse(newRotation) // RotA^(-1)
* cubeRigidBody.rotation; // RotB 
// Формул выше верна, проверял, rotX содержит искомое вращение 

// Нормализация:
    float qLen = Mathf.Sqrt(rotX.x*rotX.x+rotX.y*rotX.y+rotX.z*rotX.z + rotX.w*rotX.w);
    rotX.x /= qLen;
    rotX.y /= qLen;
    rotX.z /= qLen;
    rotX.w /= qLen;

// Поиск угла вращения:
    delta = Mathf.Acos (rotX.w) * 2f * Mathf.Rad2Deg;
  }
Во-первых delta содержит угол вращения сразу по нескольким осям
Пробовал получить угол вращения только по одной из осей (например OY) так:
delta = Mathf.Acos (rotX.w) * 2f * Mathf.Rad2Deg * rotX.y;
Не знаю можно ли так получить угол вращения только по одной из осей, но я обнаружил, что вектор вращения не задается как вектор в глобальной системе координат, в итоге непонятно какой результат получается.

Правка: 6 окт. 2017 15:54

}:+()___ [Smile]Постоялецwww6 окт. 201720:37#5
Использование терминов "кватернион" и "вращение вокруг оси X/Y/Z" (или альтернативно "углы Эйлера") в одном предложении сигнализирует о том, что тебе еще рано заниматься кватернионами.
Ну и постановка задачи бредовая:
Надо найти число X, так что
1) 5 = 2 * X,
2) число X было целым.
AlerrПостоялецwww6 окт. 201720:44#6
}:+()___ [Smile]
> Использование терминов "кватернион" и "вращение вокруг оси X/Y/Z" (или альтернативно "углы Эйлера") в одном предложении сигнализирует о том, что тебе еще рано заниматься > кватернионами.
Да я понял что кватернионы и углы эйлера совсем разные вещи. Вращать и прочее что-то обыденное делать научился, а вот как извечь вращение нигде не нашел, даже в книжке по кватернионам. Подозреваю, что кватернионы просто не предназначены под то чтобы из них можно было извлечь вращения по разным осям. 

Правка: 6 окт. 2017 20:44

}:+()___ [Smile]Постоялецwww6 окт. 201720:59#7
Alerr
Так вот, правильный ответ в том, что вращение в трехмерном пространстве — это единый и неделимый объект. Что-либо извлечь из него, в принципе, невозможно.
Его можно представить, как последовательное вращение вокруг трех осей, но, например, результат будет зависеть от порядка осей, да и само представление имеет проблемы (gimbal lock).
Плюс, стоит научиться правильно формулировать задачи, ибо я почти уверен, что тебе нужен не один из углов Эйлера, а что-то типа поворота вдоль оси Y, ближайшего к заданному.
AlerrПостоялецwww6 окт. 201722:04#8
}:+()___ [Smile]
> Плюс, стоит научиться правильно формулировать задачи, ибо я почти уверен, что тебе нужен не один из углов Эйлера, а что-то типа поворота вдоль оси Y, ближайшего к заданному.
Стараюсь формулировать с учетом того, что не знаю точно что ищу и возможно ли это найти(
У меня есть вращение rotX, которое позволяет повернуть обьект из начального положения в искомое конечное.
Это вращение rotX составное и содержит вращения сразу по нескольким осям. Мне нужно повернуть тело до конечного вращения по одному из 3-х углов, но по отдельности.
Разделить rotX на компоненты оказалось невозможно, ну и приехали. А как вращать-то тогда? Это возможно?

Правка: 6 окт. 2017 22:08

FordPerfectПостоялецwww6 окт. 201723:14#9
Alerr
>У меня есть вращение rotX, которое позволяет повернуть обьект из начального положения в искомое конечное.
Это вполне осмысленно.

>Это вращение rotX составное и содержит вращения сразу по нескольким осям.
Набор поворотов вокруг кардинальных осей (Ox, Oy, Oz) приводит к разным результирующим поворотам, в зависимости от того, в каком порядке они происходят. Соответственно, называть последовательность поворотов вокруг кардинальных осей "разложением поворота" - некорректно. Последовательностей, приводящих к данному повороту - несколько.

Если зафиксировать порядок поворотов вокруг кардинальных осей - получаем углы Эйлера (одну из 12 модификаций, ну или 24, как считать).
Т. е. кватернион в углы Эйлера преобразовать можно, но есть сильное сомнение, что это они тебе нужны.

Какая исходная задача?

AlerrПостоялецwww7 окт. 20179:57#10
FordPerfect
> Какая исходная задача?
Переписал задачу в вопросе.
}:+()___ [Smile]Постоялецwww7 окт. 201717:34#11
Alerr
> Это вращение rotX составное и содержит вращения сразу по нескольким осям.
Чем скорее ты поймешь, что это полный бред, тем лучше.
Любое вращение — это вращение вокруг одной оси, в общем случае не совпадающей с X/Y/Z, на некоторый угол.
Никаких "нескольких осей" там нету и не бывает "составных" вращений.

> Переписал задачу в вопросе.
И ничего принципиально не поменялось.
> по выбраной из осей whiteCube должен быть повернут так же как и redCube
Что ты имеешь в виду под "так же"? Подсказка: я уже писал о ближайшем подходящем вращении.

Правка: 7 окт. 2017 17:35

Megabyte-CeercopПостоялецwww7 окт. 201719:33#12
Может подойдет поекция единичного вектора повернутого через твой кватерион на выбранную плоскость?
AlerrПостоялецwww7 окт. 201721:04#13
}:+()___ [Smile]
> Чем скорее ты поймешь, что это полный бред, тем лучше.
> Любое вращение — это вращение вокруг одной оси, в общем случае не совпадающей с X/Y/Z, на некоторый угол.
> Никаких "нескольких осей" там нету и не бывает "составных" вращений.
Понял когда начал куролесить пытаясь разложить вращение.

> Что ты имеешь в виду под "так же"? Подсказка: я уже писал о ближайшем подходящем вращении.
Да, это ближайшее "подходящее" вращение. Когда я говорю про оси, я не имею в виду оси применительно к вращениям, а имею в виду то как оно визуально смотрится.
В моем примере куб визуально бы довернулся по мировой оси OY чтобы визуально "повторить" вращение красного куба.
Желательно чтобы белый куб повернулся на минимальный угол так как все стороны одинаково смотрятся, но для начала нужно хоть что-то от чего отталкиваться в поисках вращения.

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

Насчет подсказки, это оно? Гуглил по "quaternion nearest suitable rotation".

Megabyte-Ceercop
> Может подойдет поекция единичного вектора повернутого через твой кватерион на выбранную плоскость?
Не на столько продвинут в этом, не знаю что получится в результате этой операции.

}:+()___ [Smile]Постоялецwww7 окт. 201722:23#14
Alerr
> На сколько я вижу, у меня проблема с тем, что я не знаю за что зацепиться для поисках этого "ближайшего подходящего вращения".
Вот для этого и нужно учить математику, чтобы подобные вопросы решались за 5 минут без всякого гугления.

Произвольный кватернион поворота имеет вид [cht](x, y, z, w),\qquad x^2+y^2+z^2+w^2=1[/cht].
Кватернион поворота вокруг Y — [cht](0, Y, 0, W),\qquad Y^2+W^2=1[/cht].
Надо найти такие Y и W, чтобы кватернион второго типа был ближайшим для первого в смысле расстояния в четырехмерном пространстве.

+ ответ

Страницы: 1 2 Следующая

/ Форум / Программирование игр / Физика

2001—2017 © GameDev.ru — Разработка игр