GLM: มุมออยเลอร์ถึงควอเทอร์เนียน


12

ฉันหวังว่าคุณจะรู้คณิตศาสตร์ GL ( GLM ) เพราะฉันมีปัญหาฉันไม่สามารถทำลาย:

ฉันมีชุดของออยเลอร์แองเกิ้ลและฉันจำเป็นต้องทำการแก้ไขอย่างราบรื่นระหว่างพวกเขา วิธีที่ดีที่สุดคือแปลงพวกมันเป็นQuaternionsและใช้SLERP alrogirthm

ปัญหาที่ฉันมีคือวิธีการเริ่มต้น glm :: quaternion กับ Euler Angles ได้ไหม?

ฉันอ่านเอกสาร GLM ครั้งแล้วครั้งเล่าแต่ฉันไม่สามารถหาที่เหมาะสมQuaternion constructor signatureได้ซึ่งต้องใช้เวลาสามมุมของออยเลอร์ ที่ใกล้เคียงที่สุดที่ฉันพบคือ ฟังก์ชั่นangleAxis ()รับค่ามุมและแกนสำหรับมุมนั้น หมายเหตุโปรดสิ่งที่ฉันกำลังมองหา si RotX, RotY, RotZทางวิธีการแยก


สำหรับข้อมูลของคุณนี่คือลายเซ็นของฟังก์ชันangleAxis () ที่ เป็น metnioned ด้านบน:

detail::tquat< valType > angleAxis (valType const &angle, valType const &x, valType const &y, valType const &z)

คำตอบ:


13

ฉันไม่คุ้นเคยกับ GLM แต่ในกรณีที่ไม่มีฟังก์ชั่นที่จะแปลงจากมุมออยเลอร์เป็น quaternions โดยตรงคุณสามารถใช้ฟังก์ชัน "การหมุนรอบแกน" (เช่น "angleAxis") เป็นตัวคุณเอง

นี่คือวิธี (pseudocode):

Quaternion QuatAroundX = Quaternion( Vector3(1.0,0.0,0.0), EulerAngle.x );
Quaternion QuatAroundY = Quaternion( Vector3(0.0,1.0,0.0), EulerAngle.y );
Quaternion QuatAroundZ = Quaternion( Vector3(0.0,0.0,1.0), EulerAngle.z );
Quaternion finalOrientation = QuatAroundX * QuatAroundY * QuatAroundZ;

(หรือคุณอาจจำเป็นต้องสลับการคูณ quaternion รอบขึ้นอยู่กับลำดับที่ตั้งใจจะหมุนมุมออยเลอร์ของคุณ)

อีกวิธีหนึ่งจากการดูเอกสารของ GLM ดูเหมือนว่าคุณสามารถแปลงมุมออยเลอร์ -> matrix3 -> quaternion ดังนี้:

toQuat( orient3( EulerAngles ) )

คำตอบที่ดีเพราะมันไม่ชัดเจนเกี่ยวกับลำดับของแอปพลิเคชัน
Richard Fabian

@ เทรเวอร์: +1, สวัสดีเทรเวอร์ขอบคุณสำหรับคำตอบที่ดีของคุณ ดูเหมือนว่าวิธีการแก้ปัญหาที่เป็นประโยชน์มากที่สุดที่นี่ ฉันสามารถสลับไปมาระหว่างลำดับการคูณการหมุนได้อย่างง่ายดาย อาจเป็นไปได้ว่าจำนวนชุดค่าผสมนั้นเป็นเหตุผลว่าทำไมการแปลงแบบออยเลอร์ถึงการตั้งคำถามจึงไม่สามารถใช้ได้ใน GLM
Bunkai.Satori

แม้ว่าคำตอบทั้งหมดนั้นดีและมีคุณค่า แต่ในความคิดของฉันนี่เป็นคำตอบที่ดีที่สุด ผมอยากจะทำเครื่องหมายว่าเป็นคำตอบที่ได้รับการยอมรับ
Bunkai.Satori

@ เทรเวอร์: ใน Quaternion finalOrientation = QuatAroundX * QuatAroundY * QuatAroundZ; คุณคูณความหมายอะไร ฉันกำลังแปลกใจว่า GLM ไม่เกินoperator *สำหรับ Quaternion คูณดังนั้นอาจเป็นไปได้ที่ผมจะต้อง Peform คูณด้วยตนเอง
Bunkai.Satori

3
@Bunkai แนวคิดของการคูณ quaternion คล้ายกับการคูณเมทริกซ์มันไม่ได้เป็นจุดหรือข้ามผลิตภัณฑ์ หากคุณต้องการเข้าใจการใช้งานของ quaternions จากนั้นทำความคุ้นเคยกับการฝึกอบรมและทำความเข้าใจกับแกนมุมแนวคิดพื้นฐานของพวกเขาค่อนข้างคล้ายกับ quaternions คณิตศาสตร์เป็นขั้นสูงขึ้นเล็กน้อย แต่เมื่อคุณเข้าใจแกนมุมแล้ว quaternions ไม่ ห่างไกลอีกต่อไป
Maik Semder

16
glm::quat myquaternion = glm::quat(glm::vec3(angle.x, angle.y, angle.z));

ที่ไหนangleเป็นglm::vec3ที่มีสนามหันเหม้วนตามลำดับ

PS หากมีข้อสงสัยเพียงไปที่ส่วนหัวและมอง คำจำกัดความสามารถพบได้ใน glm / gtc / quaternion.hpp:

explicit tquat(tvec3<T> const & eulerAngles) {
        tvec3<T> c = glm::cos(eulerAngle * value_type(0.5));
    tvec3<T> s = glm::sin(eulerAngle * value_type(0.5));

    this->w = c.x * c.y * c.z + s.x * s.y * s.z;
    this->x = s.x * c.y * c.z - c.x * s.y * s.z;
    this->y = c.x * s.y * c.z + s.x * c.y * s.z;
    this->z = c.x * c.y * s.z - s.x * s.y * c.z;    
}

ที่quatเป็นแบบลอยสำหรับtquatพิมพ์


นั่นค่อนข้างคลุมเครือสิ่งเหล่านี้จะนำไปใช้กับอะไรบ้าง Eulers ได้รับคำสั่งให้หมุนและตัวสร้าง quaternion ที่นี่ดูเหมือนจะไม่สนใจเรื่องนั้น
Richard Fabian

คำจำกัดความของฟังก์ชั่นนั้นเหมือนกันกับของคุณ ฉันโพสต์ไว้ในคำตอบถ้ามันสำคัญ
decaviatedcaviar

ไม่ใช่ลำดับของอาร์กิวเมนต์, ลำดับของการประยุกต์ใช้การหมุน คำตอบของฉันมีการสั่งซื้อ XYZ นำมาจากบทความวิกิพีเดีย แต่เราใช้การสั่งซื้อ ZYX ของแอปพลิเคชันที่ บริษัท เก่าของฉันและ YZX ที่ปัจจุบันของฉัน มุม x ยังคงเป็นค่าแรกในรายการเวกเตอร์ / อาร์กิวเมนต์ในทุกกรณี แต่การแปลงผลลัพธ์จริงไม่เหมือนกัน
Richard Fabian

ฉันแก้ไขคำตอบสำหรับการหมุน QUAT เพื่อให้คุณสามารถดูว่าคุณสามารถเปลี่ยนลำดับได้อย่างง่ายดาย โดยค่าเริ่มต้นจะยอมรับ XYZ แต่คุณสามารถเปลี่ยนได้อย่างง่ายดาย
decaviatedcaviar

2
-1 สำหรับการไม่กล่าวถึงลำดับการหมุนซึ่งเป็นสิ่งสำคัญมากสำหรับคำถาม
Maik Semder

7

โซลูชันอยู่ในวิกิพีเดีย: http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles

ใช้ที่:

sx = sin(x/2); sy = sin(y/2); sz = sin(z/2);
cx = cos(x/2); cy = cos(y/2); cz = cos(z/2);

q( cx*cy*cz + sx*sy*sz,
   sx*cy*cz - cx*sy*sz,
   cx*sy*cz + sx*cy*sz,
   cx*cy*sz - sx*sy*cz ) // for XYZ application order

q( cx*cy*cz - sx*sy*sz,
   sx*cy*cz + cx*sy*sz,
   cx*sy*cz - sx*cy*sz,
   cx*cy*sz + sx*sy*cz ) // for ZYX application order

คอนสตรัคเตอร์สำหรับ quaternion ให้ออยเลอร์ (ที่แอพลิเคชันของการหมุนเป็น XYZ หรือ ZYX) อย่างไรก็ตามมันเป็นเพียงการรวมกันสองมุมหกของมุมออยเลอร์ คุณต้องค้นหาว่าอะไรที่มุมของออยเลอร์ถูกสร้างขึ้นเมื่อแปลงเป็นเมทริกซ์ จากนั้นจะสามารถกำหนดโซลูชันได้

ใน บริษัท เก่าที่ฉันทำงานอยู่เรามี Z เป็นตัวส่งต่อ (เช่นกราฟิกการ์ดส่วนใหญ่) ดังนั้นใบสมัครคือ ZYX และที่ บริษัท ปัจจุบันของฉันแกน Y คือส่งต่อและ Z ขึ้นไปดังนั้นใบสมัครของเราคือ YZX คำสั่งนี้เป็นคำสั่งที่คุณคูณ quaternions ของคุณเข้าด้วยกันเพื่อสร้างการแปลงสุดท้ายของคุณและลำดับการหมุนที่สำคัญคือการคูณไม่ใช่การสลับ


1
+1, สวัสดีและขอบคุณสำหรับคำตอบที่ดี ขณะที่ฉันใช้OpenGLค่า Z จะออกไปนอกหน้าจอ ในแอปพลิเคชันของฉันฉันดำเนินการตามลำดับการคูณ ZYX แต่เดิมฉันคิดว่า GLM มีฟังก์ชั่นนี้ใช้งานได้ แต่ฉันเห็นว่ามันยังไม่ได้ใช้งานดังนั้นทางเลือกหนึ่งคือการสร้างการแปลงด้วยตนเองตามที่คุณแนะนำ
Bunkai.Satori

นี่คือคำตอบที่ดีที่สุดที่นี่
ลาสม่าเซล

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.