Я провел много исследований, но действительно не могу найти, как я должен использовать кватернион, чтобы сделать следующее:
У меня есть исходная ориентация и целевая ориентация, и я пытаюсь найти кватернион определенного угла (например, 10 градусов), который идет от одной ориентации к другой.
Я пытаюсь понять кватернионы, а также хочу избежать блокировки подвеса, поэтому мне нужен ответ, который не нужно преобразовывать в углы Эйлера.
Я знаю, что есть функция Slerp, но это как «процент» вместо угла. Также я не уверен, как найти разницу между источником и целью.
В основном я пытаюсь сделать следующее, но с кватернионами вместо векторов:
Vector3 source, target; //Lets pretend they are defined
Vector3 vect_dir = target - source;
float vect_length = Mathf.Min(10f * Time.deltaTime, vect_dir.magnitude);
Vector3 answer = vect_dir.normalized * vect_length;
Кто-нибудь знает, как сделать то же самое с кватернионами? Идея состоит в том, чтобы установить значение скорости (10 в примере) по моему выбору. Это очень похоже на использование функции Slerp, за исключением того, что я хочу постоянное движение вместо движения, которое происходит быстро и постепенно замедляется. Я также хотел бы избежать использования углов Эйлера из-за карданного замка.
Quaternion.RotateTowards
Quaternion.RotateTowards
принимает Quaternion
от, Quaternion
к и float
maxDegreesDelta. Затем он возвращает тот из них, который ближе к от:
Quaternion
между от и к, что на maxDegreesDelta градусов от от
к
Таким образом, пример с Quaternion
s, который соответствует вашему, может быть записан так:
Quaternion source, target; //Lets pretend they are defined
Quaternion reachedRotation = Quaternion.RotateTowards(source, target, 10f * Time.deltaTime);
Если вам нужна разница между достигнутой точкой и source
, вы можете посчитать кватернион:
Quaternion answer = Quaternion.Inverse(source) * midpoint;
В качестве альтернативы вы можете определить разницу между target
и source
и выразить это в форме угла (величины) и оси (направления) с помощью Quaternion.ToAngleAxis
:
Quaternion difference = Quaternion.Inverse(source) * target;
Vector3 differenceAxis;
float differenceAngle;
difference.ToAngleAxis(out differenceAngle, out differenceAxis);
А затем произведите answer
, укупорив differenceAngle
:
Quaternion answer = Quaternion.AngleAxis(Mathf.Min(differenceAngle, 10f * Time.deltaTime), differenceAxis);
И если вы хотите найти вращение, которое получается в результате «включения» answer
в source
, просто перемножьте их (порядок важен):
reachedRotation = source * answer;
В качестве примечания ваш пример с Vector3
s можно записать так:
Vector3 source, target; //Lets pretend they are defined
Vector3 answer = Vector3.MoveTowards(source, target, 10f * Time.deltaTime) - source;
@ Marc477 Marc477 Я немного добавил об этом в свой ответ. Дайте мне знать, если это не совсем соответствует тому, что вы искали
@ Marc477 Marc477 Я отредактировал свой ответ, чтобы лучше ответить на ваш вопрос, как написано
Это действительно здорово!
Это отличный ответ! Как мне получить промежуточные значения, если они мне нужны? Я думаю, что смогу получить угол с помощью Quaternion.Angle. Но не уверен, как бы я получил разницу между кватернионами. (Так что vect_dir в моем примере, но для кватернионов).