2017-02-06 6 views
-3

. Бэкэнд использует повороты Эйлера по соображениям эффективности. (блокировка карданного вала не является фактором, поэтому, пожалуйста, не комментируйте).Как точно преобразовать кватернионы в Эйлера?

Если данные передают кватернион, как я могу преобразовать их в точный Эйлер?

Большинство методов, которые я видел, используют asin для оси Y, но есть рекомендуемый метод использования 3 функций atan2 для обеспечения точности.

Кроме того, я должен упомянуть, я следую OpenGL термины для представления оси, где Z представляет глубину вашего монитора, в отношении:

{ X: width, Y: height, Z: depth } 

так, если вы предоставляете пример кода, пожалуйста, предоставьте ротацию как таковой :

{ X: pitch, Y: yaw, Z: roll } 
+0

Пробовал ли вы метод 'atan2'? Если да, то в чем проблема? – BDL

+0

Нет, мне еще нужно использовать C, чтобы вы могли ожидать, что я не понимаю код ... heh – Tcll

+0

Что такое C в отношении математической концепции? В каком коде вы ссылаетесь на btw.? – BDL

ответ

1

Концепция не является тривиальной, но смотрите в исходный код. Есть много людей, которые внедрили это до вас: Quaternion.java Линия: 289, toAngles. Тот факт, что это в основном математика, должно облегчить перевод на ваш предпочтительный язык. Углы также находятся в том порядке, в котором вы запросили (шаг, рыскание, рулон)

public float[] toAngles(float[] angles) { 
    if (angles == null) { 
     angles = new float[3]; 
    } else if (angles.length != 3) { 
     throw new IllegalArgumentException("Angles array must have three elements"); 
    } 

    float sqw = w * w; 
    float sqx = x * x; 
    float sqy = y * y; 
    float sqz = z * z; 
    float unit = sqx + sqy + sqz + sqw; // if normalized is one, otherwise 
    // is correction factor 
    float test = x * y + z * w; 
    if (test > 0.499 * unit) { // singularity at north pole 
     angles[1] = 2 * FastMath.atan2(x, w); 
     angles[2] = FastMath.HALF_PI; 
     angles[0] = 0; 
    } else if (test < -0.499 * unit) { // singularity at south pole 
     angles[1] = -2 * FastMath.atan2(x, w); 
     angles[2] = -FastMath.HALF_PI; 
     angles[0] = 0; 
    } else { 
     angles[1] = FastMath.atan2(2 * y * w - 2 * x * z, sqx - sqy - sqz + sqw); // roll or heading 
     angles[2] = FastMath.asin(2 * test/unit); // pitch or attitude 
     angles[0] = FastMath.atan2(2 * x * w - 2 * y * z, -sqx + sqy - sqz + sqw); // yaw or bank 
    } 
    return angles; 
} 
+0

только что поняли, что проблемы с этим ничем не отличаются от решения вики BDL: нельзя поворачивать Y (высота монитора) за 90 °, а ориентация кажется неправильной {X : yaw, Y: roll, Z: pitch}, поместив плоскость вверх, левое крыло к вам. – Tcll

+0

Я не замечал таких проблем за время, когда я использовал двигатель (около 7 лет). Я думаю, вы также можете взглянуть на метод fromAngles, чтобы убедиться, что Quat построен правильно. – reden

+0

Я уверен, что двигатель, который вы используете, соответствует его стандарту на всем протяжении, но это стандарт YZX делает вещи все более запутанными, поэтому я и попросил XYZ. во-вторых, для моего (правильного) стандарта (Z = глубина монитора) эта ориентация означает, что вы не можете оглядываться позади вас, но только насколько ваши стороны ... вот почему я попросил 3 функции atan2.в целом, хотя это так же хорошо, как и любая другая версия этого конкретного метода, и поэтому я поддерживаю его. – Tcll