2010-11-04 43 views
12

tôi có hai ma trận xoay mô tả phép xoay tùy ý. (Tương thích với opengl 4x4)nội suy giữa các ma trận xoay

bây giờ tôi muốn nội suy giữa chúng, sao cho nó theo một đường tròn hướng tâm từ một vòng quay này sang vòng quay khác. suy nghĩ của một máy ảnh trên một chân máy tìm kiếm một cách và sau đó quay.

nếu tôi nội suy mọi thành phần tôi nhận được kết quả ép, vì vậy tôi nghĩ tôi cần phải nội suy chỉ một số thành phần nhất định của ma trận. nhưng cái nào?

Trả lời

1

Bạn cần phải chuyển đổi ma trận thành một biểu diễn khác nhau - quaternions hoạt động tốt cho điều này, và nội suy quaternions là một hoạt động được xác định rõ.

+0

cảm ơn! vậy làm thế nào tôi có thể chuyển đổi một ma trận thành một quaternion? – clamp

+0

Tôi khuyên bạn nên bắt đầu bằng cách đọc: http://en.wikipedia.org/wiki/Quaternion – tdammers

14

Bạn phải sử dụng SLERP cho các phần quay của ma trận và tuyến tính cho các phần khác. Cách tốt nhất là biến ma trận của bạn thành quaternion và sử dụng SLERP quaternion (đơn giản): http://en.wikipedia.org/wiki/Slerp.

Tôi khuyên bạn nên đọc Graphic Gems II hoặc III, cụ thể là các phần về phân tách ma trận thành các phép biến đổi đơn giản hơn. Dưới đây là Spencer W. Thomas' nguồn cho chương này:

http://tog.acm.org/resources/GraphicsGems/gemsii/unmatrix.c

Tất nhiên, tôi đề nghị bạn học cách để làm điều này cho mình. Nó thực sự không phải là khó, chỉ cần rất nhiều đại số gây phiền nhiễu. Và cuối cùng, đây là một bài báo tuyệt vời về cách để biến một ma trận vào một quaternion, và trở lại, bởi phần mềm Mã sản phẩm: http://cache-www.intel.com/cd/00/00/29/37/293748_293748.pdf


Sửa: Đây là công thức khá nhiều tất cả mọi người trích dẫn, đó là từ một SIGGRAPH 1985 giấy.

alt text

đâu:

- qm = interpolated quaternion 
- qa = quaternion a (first quaternion to be interpolated between) 
- qb = quaternion b (second quaternion to be interpolated between) 
- t = a scalar between 0.0 (at qa) and 1.0 (at qb) 
- θ is half the angle between qa and qb 

Code:

quat slerp(quat qa, quat qb, double t) { 
    // quaternion to return 
    quat qm = new quat(); 
    // Calculate angle between them. 
    double cosHalfTheta = qa.w * qb.w + qa.x * qb.x + qa.y * qb.y + qa.z * qb.z; 
    // if qa=qb or qa=-qb then theta = 0 and we can return qa 
    if (abs(cosHalfTheta) >= 1.0){ 
     qm.w = qa.w;qm.x = qa.x;qm.y = qa.y;qm.z = qa.z; 
     return qm; 
    } 
    // Calculate temporary values. 
    double halfTheta = acos(cosHalfTheta); 
    double sinHalfTheta = sqrt(1.0 - cosHalfTheta*cosHalfTheta); 
    // if theta = 180 degrees then result is not fully defined 
    // we could rotate around any axis normal to qa or qb 
    if (fabs(sinHalfTheta) < 0.001){ // fabs is floating point absolute 
     qm.w = (qa.w * 0.5 + qb.w * 0.5); 
     qm.x = (qa.x * 0.5 + qb.x * 0.5); 
     qm.y = (qa.y * 0.5 + qb.y * 0.5); 
     qm.z = (qa.z * 0.5 + qb.z * 0.5); 
     return qm; 
    } 
    double ratioA = sin((1 - t) * halfTheta)/sinHalfTheta; 
    double ratioB = sin(t * halfTheta)/sinHalfTheta; 
    //calculate Quaternion. 
    qm.w = (qa.w * ratioA + qb.w * ratioB); 
    qm.x = (qa.x * ratioA + qb.x * ratioB); 
    qm.y = (qa.y * ratioA + qb.y * ratioB); 
    qm.z = (qa.z * ratioA + qb.z * ratioB); 
    return qm; 
} 

Từ: http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/

+0

ok, cảm ơn hãy nói tôi sử dụng Quaternions để thay thế. sao tôi chỉ nội suy từng thành phần trong 4 thành phần để có được sự chuyển tiếp suôn sẻ? – clamp

+0

Đã chỉnh sửa câu trả lời của tôi bằng công thức và một số mã dễ tiêu hóa hơn. –

+0

Bạn nhóm liên kết đầu tiên không còn hoạt động nữa :( – Narfanator

Các vấn đề liên quan