Углы Эйлера для направления относительно повернутой системы локальных осей в unity

#unity3d #rotation #euler-angles

#unity3d #вращение #углы Эйлера

Вопрос:

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

Введите описание изображения здесь

Я могу сделать это, проецируя направление от начала координат до цели в моей плоскости, а затем используя Vector3.Угол (начало координат в прямом направлении, проекционное направление в плоскости).

Есть ли способ получить это аналогичным образом, Quaternion.FromToRotation(from, to).eulerAngles; но с углами Эйлера, относительно системы координат, которая не является мировой, а локально повернутой (та, которая представлена повернутой плоскостью на рисунке выше)?

Так что желаемый угол для поворота по локальной оси y: Quaternion.FromToRotation(from, to).localEulerAngles.y , поскольку локальные углы Эйлера будут (0, -желаемый угол, 0), на основе этого подхода.

Или есть более прямой способ, чем тот, которым я этого добился?

Комментарии:

1. Я бы посоветовал вам немного улучшить свой вопрос, лично мне немного сложно понять, о чем именно вы спрашиваете. Если вы знаете угол и векторы, в чем проблема?

2. Спасибо за ваш комментарий и предложение. Вопрос немного сложно объяснить, я сделал все возможное. Вопрос в том, что, хотя я добиваюсь своих результатов, я просил лучшего или более прямого подхода. Поскольку Quaternion.FromToRotation(from, to).eulerAngles они уже существуют в unity, с системой мировых осей в качестве эталона, я спрашиваю, есть ли другое аналогичное решение для других осей, которые не являются мировыми, чтобы получить углы для этой повернутой системы (локальной) вместо системы мировых осей.

3. Я объясняю проблему, с которой я столкнулся, и как я ее решил, чтобы показать, как на пути к решению я подошел к вопросу, который я задаю. Надеюсь, это имеет смысл. Дайте мне знать все, что может быть непонятно.

4. Это не проверено, но… Если я все правильно понимаю, я думаю, вы можете использовать Transform.InverseTransformPoint для получения локальных координат цели и использовать Quaternion.FromToRotation , где «от» будет target_direction_local и «до» будет target_direction_local с y=0 ( я думаю, это создает поворот от цели к плоскости в локальной системе координат ). Затем используйте Quaternion.eulerAngles , чтобы получить его локальные углы. Наконец, создайте новый кватерион с Quaterinion.Euler где x ваш угол и y, z являются углами из eulerAngles.

5. большое спасибо, что нашли время, чтобы понять мой вопрос и ваш комментарий. Я знаком с Transform.InverseTransformPoin so, поэтому ваше предложение имеет смысл для меня. Я попробую это как можно скорее и сообщу вам, если это сработает!

Ответ №1:

Если я правильно вас понимаю, вероятно, есть много возможных путей.

Я думаю, вы могли бы, например, использовать Quaternion.ToAngleAxis , который возвращает угол и ось вокруг и который был повернут. Затем эту ось можно преобразовать в локальное пространство вашего объекта

 public Vector3 GetLocalEulerAngles(Transform obj, Vector3 vector)
{
    // As you had it already, still in worldspace
    var rotation = Quaternion.FromToRotation(obj.forward, vector);
    rotation.ToAngleAxis(out var angle, out var axis);

    // Now convert the axis from currently world space into the local space
    // Afaik localAxis should already be normalized
    var localAxis = obj.InverseTransformDirection(axis);

    // Or make it float and only return the angle if you don't need the rest anyway
    return localAxis * angle;
}
  

В качестве альтернативы, как уже упоминалось, я думаю, да, вы также можете просто сначала преобразовать другой вектор в локальное пространство, а затем Quaternion.FromToRotation уже должен быть в локальном пространстве

 public Vector3 GetLocalEulerAngles(Transform obj, Vector3 vector)
{
    var localVector = obj.InverseTransformDirection(vector);

    // Now this already is a rotation in local space
    var rotation = Quaternion.FromToRotation(Vector3.forward, localVector);
    
    return rotation.eulerAngles;
}
  

Комментарии:

1. Большое спасибо за ваш ответ. Я попробую это и дам вам знать!!

2. Вы это сделали. Оба примера работают. Большое вам спасибо за то, что нашли время, чтобы ответить на вопрос и предоставить 2 подхода. Хотя я знал, как это сделать, эти два способа намного проще, и мое понимание поворотов улучшается.

3. Однако я не понимаю, почему во втором примере var rotation = Quaternion.FromToRotation(Vector3.forward, localVector); это вращение в локальном пространстве, поскольку localVector находится в локальном пространстве, но Vector3.forward является мировым форвардом. он работает с Vector3.forward углом, который мне нужен, и дает нужный угол, но я бы сказал, что это obj.forward имело бы больше смысла или, по крайней мере, я бы попробовал obj.forward раньше Vector3.forward . Вы понимаете мою точку зрения?

4. О, я понял. Оба вектора должны находиться в одном и том же пространстве. World’s.forward в локальном пространстве не (0,0,1), так же, как obj.forward — это не 0,0,1 в пространстве миров, а разложение по оси миров. Итак, в локальном пространстве Vector3.forward = 0,0,1 — это вектор, от которого мне нужно отклониться, чтобы достичь желаемого угла. На самом деле я ввел obj.forwar и вектор как в мировом пространстве, так и в ожидаемом режиме. Это так удивительно! большое спасибо!

5. @rustyBucketBay да, вы это уже поняли!;) Мне особенно нравится, что это также помогло вам понять это самостоятельно. В моих глазах это то, чем является (должна быть) эта страница в основном — помочь вам понять, а не просто предоставить готовый к использованию фрагмент кода. Так что очень рад помочь!