GLM: Euler Angles to Đệ tứ


12

Tôi hy vọng bạn biết GL Toán học ( GLM ) vì tôi gặp vấn đề, tôi không thể phá vỡ:

Tôi có một bộ Euler Angles và tôi cần thực hiện phép nội suy trơn tru giữa chúng. Cách tốt nhất là chuyển đổi chúng thành Đệ tứ và áp dụng thuật toán SLERP.

Vấn đề tôi có là làm thế nào để khởi tạo glm :: quancyion với Euler Angles, làm ơn?

Tôi đã đọc Tài liệu GLM nhiều lần, nhưng tôi không thể tìm thấy thích hợp Quaternion constructor signature, điều đó sẽ mất ba Góc Euler. Hàm gần nhất tôi tìm thấy là hàm angleAxis () , lấy giá trị góc và trục cho góc đó. Lưu ý, xin vui lòng, những gì tôi đang tìm si một cách, làm thế nào để phân tích RotX, RotY, RotZ.


Để biết thông tin của bạn, đây là chữ ký hàm angleAxis () được đo lường ở trên :

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

Câu trả lời:


13

Tôi không quen thuộc với GLM, nhưng trong trường hợp không có chức năng chuyển đổi trực tiếp từ các góc Euler thành các bậc bốn, bạn có thể sử dụng các hàm "xoay quanh một trục" (chẳng hạn như "angleAxis") cho chính nó.

Đây là cách (mã giả):

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;

(Hoặc bạn có thể cần phải thay đổi các bội số bậc bốn xung quanh, tùy thuộc vào thứ tự xoay góc euler của bạn được áp dụng)

Cách khác, từ việc xem qua tài liệu của GLM, có vẻ như bạn có thể chuyển đổi các góc euler -> matrix3 -> quernion như thế này:

toQuat( orient3( EulerAngles ) )

câu trả lời tốt bởi vì nó ít mơ hồ về thứ tự ứng dụng.
Richard Fabian

@Trevor: +1, Xin chào Trevor, cảm ơn vì câu trả lời tốt của bạn. Đây có vẻ là giải pháp thiết thực nhất ở đây. Tôi có thể dễ dàng chuyển đổi giữa thứ tự nhân xoay. Có thể, số lượng kết hợp là lý do, tại sao chuyển đổi Euler Angle sang Quaterion không có sẵn trong GLM.
Bunkai.Satori

Mặc dù tất cả các câu trả lời là tốt và có giá trị, theo tôi, đây là câu trả lời thiết thực nhất. Tôi muốn đánh dấu nó là Câu trả lời được chấp nhận .
Bunkai.Satori

@Trevor: Trong Quancyion FinalOrientation = QuatAroundX * QuatAroundY * QuatAroundZ;, bạn có ý nghĩa gì về phép nhân ? Tôi ngạc nhiên, GLM đó, không quá tải operator *cho phép nhân Quancyion, vì vậy có thể, tôi sẽ phải thực hiện phép nhân bằng tay .
Bunkai.Satori

3
@Bunkai khái niệm về phép nhân bậc bốn tương tự như phép nhân ma trận, nó không phải là dấu chấm hay sản phẩm chéo. Nếu bạn muốn hiểu cách sử dụng các bậc bốn, sau đó làm quen với ma trận và hiểu các góc trục, khái niệm cơ bản của chúng khá giống với các bậc bốn, toán học tiến bộ hơn một chút, nhưng một khi bạn đã hiểu các góc của trục, thì các bậc bốn không xa rồi nữa.
Maik

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

Trường hợp anglelà một sânglm::vec3 chứa , ngáp, cuộn tương ứng.

Tái bút Nếu nghi ngờ, chỉ cần đi đến các tiêu đề và nhìn. Định nghĩa có thể được tìm thấy trong glm / gtc / qu Parention.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;    
}

Trường hợp quatlà một typedef nổi cho tquat.


Điều đó khá mơ hồ, những thứ này sẽ được áp dụng theo thứ tự nào? Eulers được ra lệnh quay và người xây dựng bậc bốn ở đây dường như không quan tâm đến điều đó.
Richard Fabian

Định nghĩa hàm giống hệt như của bạn; Tôi đã đăng nó trong câu trả lời của tôi nếu nó quan trọng.
giảm tốc

không phải thứ tự của các đối số, thứ tự áp dụng xoay vòng. Câu trả lời của tôi chứa thứ tự XYZ, được lấy từ bài viết trên wikipedia, tuy nhiên, chúng tôi sử dụng đơn đặt hàng ứng dụng ZYX tại công ty cũ của tôi và YZX ở bài viết hiện tại của tôi. góc x vẫn là giá trị đầu tiên trong danh sách vectơ / đối số trong mọi trường hợp, nhưng biến đổi kết quả thực tế không giống nhau.
Richard Fabian

Tôi đã sửa câu trả lời của mình cho rotationQuat, để bạn có thể thấy cách bạn có thể dễ dàng thay đổi thứ tự. Theo mặc định, nó chấp nhận XYZ, nhưng bạn có thể dễ dàng thay đổi điều đó.
giảm tốc

2
-1 vì không đề cập đến thứ tự xoay vòng, điều này rất quan trọng cho câu hỏi
Maik Semder

7

Giải pháp có trong wikipedia: http://en.wikipedia.org/wiki/Conversion_b between_qu Parentions_and_Euler_angles

sử dụng:

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

Các nhà xây dựng cho một bậc bốn, được đưa ra một Euler (trong đó ứng dụng xoay là XYZ hoặc ZYX). Tuy nhiên, đó chỉ là hai trong số sáu kết hợp góc Euler có thể. Bạn thực sự cần phải tìm ra thứ tự các góc Euler được xây dựng khi chuyển đổi sang ma trận biến đổi. Chỉ sau đó giải pháp có thể được xác định.

Ở công ty cũ tôi làm việc, chúng tôi có Z về phía trước (giống như hầu hết các card đồ họa) nên thứ tự ứng dụng là ZYX, và tại công ty hiện tại của tôi trục Y là chuyển tiếp và Z lên, vì vậy đơn đặt hàng ứng dụng của chúng tôi là YZX. Thứ tự này là thứ tự bạn nhân các nhóm bậc bốn của bạn với nhau để tạo ra biến đổi cuối cùng của bạn và thứ tự quan trọng đối với phép quay là phép nhân không giao hoán.


1
+1, xin chào và cảm ơn vì câu trả lời tuyệt vời. Khi tôi sử dụng OpenGL , giá trị Z sẽ biến mất khỏi màn hình. Trong ứng dụng của tôi, tôi thực hiện thứ tự nhân ZYX . Ban đầu, tôi nghĩ rằng GLM có sẵn chức năng này, nhưng tôi thấy, họ chưa triển khai nó, vì vậy một cách khác là tạo chuyển đổi theo cách thủ công , như bạn đề xuất.
Bunkai.Satori

Đây là câu trả lời tốt nhất ở đây.
plasmacel

1
vec3 myEuler (fAngle[0],fAngle[1],fAngle[2]);
glm::quat myQuat (myEuler);

fAngle phải bằng radian!


2
Đây có phải là một trò đùa? Hay bạn chỉ không đọc các câu trả lời khác (đặc biệt là của Daniel)?
Chris nói phục hồi Monica
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.