Как я могу изменить только одну ось кватерниона?

Я создал два объекта в Unity3D, представляющие плечо (родительское) и предплечье (дочернее), соединенные суставом персонажа. Вращение этих объектов управляется двумя кватернионами, которые я собираю из IMU, расположенных на плече и предплечье. Я калибрую оба кватерниона. Моя цель — визуализировать сгибание/разгибание локтя.

Q в названии указывает, что это кватернион. QImu указывает, что это кватернион из IMU. Qstart указывает, что это начальная начальная ориентация IMU.

// upperarm script attached to upperarm object
if (Input.GetKeyDown(KeyCode.Space))
        {
            QstartUpperArm = QimuUpperArm;
        }

        transform.localRotation = QstartUpperArm * Quaternion.Inverse(QimuUpperArm);
// lowerarm script attached to lowerarm object
if (Input.GetKeyDown(KeyCode.Space))
        {
            QstartLowerArm = QimuLowerArm;
        }

        QimuLowerArm = QstartLowerArm * Quaternion.Inverse(QimuLowerArm);
transform.localrotation = Quaternion.Inverse(Qstart2 * Quaternion.Inverse(Qimu2)) * Qimu1new;

Объект Upperarm вращается точно так, как ожидалось. Однако у объекта предплечья одна ось Y перевернута. Все остальные оси в порядке. Как я могу изменить знак этой одной оси с помощью кватерниона?


person pvand    schedule 15.07.2019    source источник
comment
Поворот вокруг перпендикулярной оси на 180 градусов. К сожалению, вы не можете инвертировать только одну ось, не используя отрицательную шкалу или не меняя хиральность всей системы.   -  person Leo Bartkus    schedule 15.07.2019
comment
Можете ли вы объяснить немного больше, что вы подразумеваете под осью Y перевернутой? Вы говорите, что он вращается в неправильном направлении вокруг локальной оси y плеча? Нам могут понадобиться изображения или видео, чтобы получить представление о том, что здесь происходит.   -  person Ruzihm    schedule 15.07.2019
comment
Это своего рода выстрел в темноте, когда вы не видите, что именно происходит... Попробуйте так: Quaternion reversedY = Quaternion.Inverse(Qstart2 * Quaternion.Inverse(Qimu2)) * Qimu1new; transform.localrotation = Quaternion.Euler(Vector3.Scale(reversedY, new Vector3(1f, -1f, 1f) ) );   -  person Ruzihm    schedule 15.07.2019
comment
@pvand дайте нам знать, если это сработает   -  person Ruzihm    schedule 16.07.2019
comment
Я нашел что-то в Интернете, у которого была похожая проблема, решение: Vector3 myEulerAngles = QimuLowerArm.eulerAngles; Quaternion invertedRotation = Quaternion.Euler(myEulerAngles.x, -myEulerAngles.y, myEulerAngles.z); transform.localRotation = invertedRotation; Итак, я думаю, что ваше решение похоже.   -  person pvand    schedule 16.07.2019


Ответы (1)


Вы не должны делать это непосредственно в файле Quaternion. Похоже, вы путаете Quaternion (который имеет 4 компонента x,y,z,w) с представлением пространства Эйлера в x,y,z.

Вы можете попробовать использовать что-то вроде

var invertedRotation = Quaternion.Euler(Vector3.Scale(QimuLowerArm.eulerAngles, Vector3.up * -1));

В зависимости от того, какое вращение вам нужно инвертировать (не ясно видел это в вашем коде).

  • eulerAngles возвращает представление Эйлера Quaternion

  • Vector3.Scale умножается на Vector3 по компонентам. В данном случае Vector3.up * -1 == new Vector3(0, -1, 0);

  • Quaternion.Euler генерирует Quaternion для поворота на заданные углы Эйлера. Здесь следует отметить, что повороты применяются в порядке x, затем z, затем y, но, поскольку вы инвертируете последний, все должно быть в порядке.


Альтернативный афаик (не очень уверенный в этом) состоит в том, чтобы

  • отрицать соответствующий компонент оси
  • отрицать компонент w

Я все еще не стал бы делать это непосредственно в кватернионе, потому что порядок имеет большое значение, но, например,

var invertedRotation = new Quaternion (QimuLowerArm.x, - QimuLowerArm.y, QimuLowerArm.z, -QimuLowerArm.w);
person derHugo    schedule 15.07.2019
comment
Первое решение работает, когда я держу плечо в одном и том же вращении. Однако, если я начну вращать верхнюю часть руки, нижняя часть руки начнет вращаться вокруг оси, которую я только что повернул вспять. Другими словами, я начинаю сгибаться, когда поворачиваю предмет плеча вбок... - person pvand; 15.07.2019