2010-11-04 8 views
12

के बीच इंटरपोलेट मेरे पास दो रोटेशन मैट्रिस हैं जो मनमाने ढंग से घूर्णन का वर्णन करते हैं। (4x4 opengl संगत)रोटेशन मैट्रिस

अब मैं उनके बीच अंतरण करना चाहता हूं, ताकि यह एक घूर्णन से दूसरे में एक रेडियल पथ का अनुसरण कर सके। एक तिपाई पर एक कैमरे के बारे में सोचें और एक तरफ घूमते हुए।

यदि मैं प्रत्येक घटक को इंटरपोलेट करता हूं तो मुझे निचोड़ने का परिणाम मिलता है, इसलिए मुझे लगता है कि मुझे मैट्रिक्स के केवल कुछ घटकों को अलग करने की आवश्यकता है। लेकिन कौन सा?

उत्तर

1

आपको मैट्रिक्स को एक अलग प्रतिनिधित्व में परिवर्तित करने की आवश्यकता है - quaternions इसके लिए अच्छी तरह से काम करते हैं, और quaternions interpolating एक अच्छी तरह से परिभाषित ऑपरेशन है।

+0

धन्यवाद! तो मैं एक मैट्रिक्स को quaternion में कैसे परिवर्तित कर सकता हूँ? – clamp

+0

मेरा सुझाव है कि आप इसे पढ़कर शुरू करें: http://en.wikipedia.org/wiki/Quaternion – tdammers

14

आपको मैट्रिस के घूर्णन भागों के लिए SLERP का उपयोग करना होगा, और अन्य भागों के लिए रैखिक। सबसे अच्छा तरीका है कि अपने मैट्रिस को quaternions में बदलना और (सरल) quaternion SLERP का उपयोग करें: http://en.wikipedia.org/wiki/Slerp

मैं ग्राफ़िक रत्न II या III पढ़ने का सुझाव देता हूं, विशेष रूप से मैट्रिक्स को सरल परिवर्तनों में विघटित करने के बारे में अनुभाग। यहाँ इस अध्याय के लिए स्पेंसर डब्ल्यू थॉमस 'स्रोत है:

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

बेशक

, मैं सुझाव है कि आप कैसे इस खुद कर सीखते हैं। यह वास्तव में मुश्किल नहीं है, बस बहुत परेशान बीजगणित। http://cache-www.intel.com/cd/00/00/29/37/293748_293748.pdf


संपादित: और अंत में, यहाँ कैसे एक चौका में एक मैट्रिक्स चालू करने के लिए, और वापस, आईडी सॉफ्टवेयर के द्वारा पर एक बड़ा कागज है यह, सूत्र काफी हर किसी का हवाला देते है यह एक 1985 SIGGRAPH से है कागज।

alt text

कहाँ:

- 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 

कोड:

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; 
} 

से: http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/

+0

ठीक है, धन्यवाद मान लें कि मैं इसके बजाय Quaternions का उपयोग करता हूं। क्या मैं एक चिकनी संक्रमण प्राप्त करने के लिए बस 4 घटकों में से प्रत्येक को अलग करता हूं? – clamp

+0

मेरे उत्तर को फॉर्मूला और पचाने के लिए कुछ आसान कोड के साथ संपादित किया। –

+0

आप लिंक का पहला समूह अब काम नहीं करते हैं :( – Narfanator

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

  • कोई संबंधित समस्या नहीं^_^