2012-06-19 13 views
11

मैं परीक्षण quaternion के लिए lib glm (http://glm.g-truc.net/) का उपयोग कर रहा हूं लेकिन मुझे कोई समस्या है; जब मैं यूलर कोण को quaternion में परिवर्तित करता हूं तो तत्काल रूप से euler कोणों के लिए quaternion, मेरा परिणाम मेरे प्रारंभिक यूलर कोण से बिल्कुल अलग हैं। क्या यह सामान्य है? क्या ऐसा हो सकता है क्योंकि घूर्णन संचारक नहीं हैं?क्वाटरनियन के लिए यूलर कोण तो क्लेटरनियन euler कोण

कोड परीक्षण:

#include <glm\quaternion.hpp> 
#include <math.h> 

#define PI M_PI 
#define RADTODEG(x) ((x) * 180.0/PI) 
#define DEGTORAD(x) ((x) * PI/180.0) 

int   main(void) 
{ 
    float RotX = 90.f; 
    float RotY = 180.f; 
    float RotZ = -270.f; 

    if (RotX || RotY || RotZ) 
    { 
     std::cout << "Init: x= " << RotX << ", y= " << RotY << ", z= " << RotZ << "\n"; 
     glm::quat key_quat(glm::detail::tvec3<float>(DEGTORAD(RotX), 
                DEGTORAD(RotY), 
                DEGTORAD(RotZ))); 
     glm::detail::tvec3<float> v = glm::eulerAngles(key_quat); 

     /* // the result is even worse with this code here 
     RotX = RADTODEG(v.x); 
     RotY = RADTODEG(v.y); 
     RotZ = RADTODEG(v.z); 
     */ 

     RotX = v.x; 
     RotY = v.y; 
     RotZ = v.z; 

     std::cout << "Final: x= " << RotX << ", y= " << RotY << ", z= " << RotZ << "\n"; 
    } 
    return (0); 
} 

परिणाम:

Init: x= 90, y= 180, z= -270 
Final: x= -90, y= -3.41509e-006, z= -90 

अग्रिम धन्यवाद ओ/

उत्तर

16

हाँ, यह सामान्य है। There are 2 ways यूलर कोणों के साथ समान रोटेशन का प्रतिनिधित्व करने के लिए।

मुझे व्यक्तिगत रूप से यूलर कोण पसंद नहीं हैं, they mess up the stability of your app. मैं उनसे बचूंगा। इसके अलावा, वे not very handy या तो हैं।

+1

धन्यवाद उपयोगी का जवाब:

यहाँ कोड का एक टुकड़ा जो मेरे लिए काम करता है। प्रभावी रूप से, मेरे इंजन में, मैं अपनी वस्तुओं को घुमाने के लिए quaternion का उपयोग करता हूं। तो, उपयोगकर्ता फोकक्शन का उपयोग कर सकते हैं; SetRotation और GetRotation (3 यूलर-कोण के साथ)। इस फॉनक्शन में, मैं ऑब्जेक्ट क्वाटरनियन पर काम करता हूं और मैं उपयोगकर्ता के लिए यूलर-एंगल को सहेजता हूं। यदि आप कहते हैं कि क्वाटरनियंस के साथ यूलर कोणों के साथ इसके घूर्णन को निर्दिष्ट करना बहुत आसान है ... (मैं जो भी लिंक करता हूं उसे पढ़ने/देखने के लिए जा रहा हूं। मैं वापस आऊंगा) – user1466739

+0

हां, मैं मानता हूं, उपयोगकर्ता के साथ संवाद करते समय यूलर कोण उपयोगी हो सकते हैं। – Ali

+0

ठीक है। मैंने जो पुस्तक आपको बताया वह मैंने पढ़ा और अब मैं सबकुछ समझ गया। आपका बहुत बहुत धन्यवाद। – user1466739

7

आप अंत तो यूलर कोण करने के लिए चार का समुदाय के ज़रूरत है, लेकिन आप एक मनमाना रोटेशन आदेश की जरूरत है, मैं रूपांतरण कोड के साथ एक साइट भर में आया था। कभी-कभी चाल सिर्फ सही रोटेशन ऑर्डर ढूंढ रही है। (बीटीडब्ल्यू, ऑर्डर जिनके पास XYX की तरह दो बार एक ही अक्षर है, उचित यूलर कोण हैं, लेकिन XYZ जैसे लोग टेट-ब्रायन कोण हैं)।

यहाँ लिंक है: http://bediyap.com/programming/convert-quaternion-to-euler-rotations/

और यहाँ कोड है:

/////////////////////////////// 
// Quaternion to Euler 
/////////////////////////////// 
enum RotSeq{zyx, zyz, zxy, zxz, yxz, yxy, yzx, yzy, xyz, xyx, xzy,xzx}; 

void twoaxisrot(double r11, double r12, double r21, double r31, double r32, double res[]){ 
    res[0] = atan2(r11, r12); 
    res[1] = acos (r21); 
    res[2] = atan2(r31, r32); 
} 

void threeaxisrot(double r11, double r12, double r21, double r31, double r32, double res[]){ 
    res[0] = atan2(r31, r32); 
    res[1] = asin (r21); 
    res[2] = atan2(r11, r12); 
} 

void quaternion2Euler(const Quaternion& q, double res[], RotSeq rotSeq) 
{ 
    switch(rotSeq){ 
    case zyx: 
     threeaxisrot(2*(q.x*q.y + q.w*q.z), 
        q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z, 
        -2*(q.x*q.z - q.w*q.y), 
        2*(q.y*q.z + q.w*q.x), 
        q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z, 
        res); 
     break; 

    case zyz: 
     twoaxisrot(2*(q.y*q.z - q.w*q.x), 
        2*(q.x*q.z + q.w*q.y), 
        q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z, 
        2*(q.y*q.z + q.w*q.x), 
        -2*(q.x*q.z - q.w*q.y), 
        res); 
     break; 

    case zxy: 
     threeaxisrot(-2*(q.x*q.y - q.w*q.z), 
         q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z, 
         2*(q.y*q.z + q.w*q.x), 
        -2*(q.x*q.z - q.w*q.y), 
         q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z, 
         res); 
     break; 

    case zxz: 
     twoaxisrot(2*(q.x*q.z + q.w*q.y), 
        -2*(q.y*q.z - q.w*q.x), 
        q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z, 
        2*(q.x*q.z - q.w*q.y), 
        2*(q.y*q.z + q.w*q.x), 
        res); 
     break; 

    case yxz: 
     threeaxisrot(2*(q.x*q.z + q.w*q.y), 
        q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z, 
        -2*(q.y*q.z - q.w*q.x), 
        2*(q.x*q.y + q.w*q.z), 
        q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z, 
        res); 
     break; 

    case yxy: 
     twoaxisrot(2*(q.x*q.y - q.w*q.z), 
        2*(q.y*q.z + q.w*q.x), 
        q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z, 
        2*(q.x*q.y + q.w*q.z), 
        -2*(q.y*q.z - q.w*q.x), 
        res); 
     break; 

    case yzx: 
     threeaxisrot(-2*(q.x*q.z - q.w*q.y), 
         q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z, 
         2*(q.x*q.y + q.w*q.z), 
        -2*(q.y*q.z - q.w*q.x), 
         q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z, 
         res); 
     break; 

    case yzy: 
     twoaxisrot(2*(q.y*q.z + q.w*q.x), 
        -2*(q.x*q.y - q.w*q.z), 
        q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z, 
        2*(q.y*q.z - q.w*q.x), 
        2*(q.x*q.y + q.w*q.z), 
        res); 
     break; 

    case xyz: 
     threeaxisrot(-2*(q.y*q.z - q.w*q.x), 
        q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z, 
        2*(q.x*q.z + q.w*q.y), 
        -2*(q.x*q.y - q.w*q.z), 
        q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z, 
        res); 
     break; 

    case xyx: 
     twoaxisrot(2*(q.x*q.y + q.w*q.z), 
        -2*(q.x*q.z - q.w*q.y), 
        q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z, 
        2*(q.x*q.y - q.w*q.z), 
        2*(q.x*q.z + q.w*q.y), 
        res); 
     break; 

    case xzy: 
     threeaxisrot(2*(q.y*q.z + q.w*q.x), 
        q.w*q.w - q.x*q.x + q.y*q.y - q.z*q.z, 
        -2*(q.x*q.y - q.w*q.z), 
        2*(q.x*q.z + q.w*q.y), 
        q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z, 
        res); 
     break; 

    case xzx: 
     twoaxisrot(2*(q.x*q.z - q.w*q.y), 
        2*(q.x*q.y + q.w*q.z), 
        q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z, 
        2*(q.x*q.z + q.w*q.y), 
        -2*(q.x*q.y - q.w*q.z), 
        res); 
     break; 
    default: 
     std::cout << "Unknown rotation sequence" << std::endl; 
     break; 
    } 
} 
0

यूलर -> Quaternion

Three.js से निकाले गए। यह करने के लिए

function eulerToQuaternion(eulerXYZ) { 
 
    var c1 = Math.cos(eulerXYZ[0]/2), 
 
    c2 = Math.cos(eulerXYZ[1]/2), 
 
    c3 = Math.cos(eulerXYZ[2]/2), 
 
    s1 = Math.sin(eulerXYZ[0]/2), 
 
    s2 = Math.sin(eulerXYZ[1]/2), 
 
    s3 = Math.sin(eulerXYZ[2]/2), 
 
    x = s1 * c2 * c3 + c1 * s2 * s3, 
 
    y = c1 * s2 * c3 - s1 * c2 * s3, 
 
    z = c1 * c2 * s3 + s1 * s2 * c3, 
 
    w = c1 * c2 * c3 - s1 * s2 * s3; 
 

 
    return [x, y, z, w]; 
 
}; 
 

 
function calculate() { 
 
    var quat = eulerToQuaternion([document.querySelector('#x').value, document.querySelector('#y').value, document.querySelector('#z').value]); 
 

 
    document.querySelector('#result').innerHTML = quat.join(' &nbsp; '); 
 
}
<h3>Euler radians in XYZ order:</h3> 
 
<fieldset> 
 
    <label>X: 
 
    <input id="x" value="1.5" /> 
 
    </label> 
 
    <label>Y: 
 
    <input id="y" value="1" /> 
 
    </label> 
 
    <label>Z: 
 
    <input id="z" value="0" /> 
 
    </label> 
 
    <button onClick="calculate()">To Quaternion</button> 
 
</fieldset> 
 
<h3>X Y Z W result:</h3> 
 
<div id="result"></div>

संबंधित मुद्दे