2012-05-19 17 views
5

को कैसे बाधित करें 3 डी रोटेशन को बाधित करने का सही/सर्वोत्तम तरीका क्या है (यूलर कोण और/या quaternions का उपयोग करके)?3 डी रोटेशन (यूलर)

ऐसा लगता है कि ऐसा करने के मेरे तरीके में कुछ गड़बड़ है। मैं एनीमेशन के लिए कंकाल पदानुक्रम में हड्डियों के घूर्णन को लागू कर रहा हूं, और हड्डियां कभी-कभी गलत अभिविन्यास में "कूद" लगती हैं, और व्यक्तिगत यूलर घटक अपनी श्रेणियों के विपरीत छोर पर घूमते हैं।

मैं वर्तमान अभिविन्यास का प्रतिनिधित्व करने के लिए यूलर कोण का उपयोग कर रहा हूं, घुमावदार करने के लिए quaternions में परिवर्तित, और प्रत्येक Euler कोण धुरी स्वतंत्र रूप से clamping।

Euler min = ...; 
Euler max = ...; 

Quat rotation = ...; 
Euler eCurrent = ...; 

// do rotation 
Quat qCurrent = eCurrent.toQuat(); 
qCurrent = qCurrent * rotation; 
eCurrent = qCurrent.toEuler(); 

// constrain 
for (unsigned int i = 0; i < 3; i++) 
    eCurrent[i] = clamp(eCurrent[i], min[i], max[i]); 
+0

आम तौर पर quaternions का उपयोग करना बेहतर है, क्योंकि वे यूलर कोणों की सीमाओं से ग्रस्त नहीं हैं (जैसे जिम्बल लॉक, जो संभवतः आप अनुभव कर रहे हैं)। जब भी आपको जटिल घूर्णन की आवश्यकता होती है (उदाहरण के लिए 3 अक्ष पर) quaternions का उपयोग करें। यूलर कोण साधारण लोगों पर बस ठीक है। –

+0

कारण मैं यूलर कोण का उपयोग कर रहा हूं इसलिए मैं उन्हें रोक सकता हूं। मुझे नहीं पता कि quaternions को कैसे रोकें। – KTC

+0

कृपया पढ़ें http://www.geometrictools.com/Documentation/ConstrainedQuaternions.pdf –

उत्तर

0

समस्या है कि यहाँ की कमी आप आवेदन कर रहे रोटेशन से कोई संबंध नहीं लागू किया जा है: यहाँ सी ++ मूल रूप से दिखा कि मैं क्या कर रहा हूँ छद्म कोड है। एक वैचारिक दृष्टिकोण से आप यही हासिल करने की कोशिश कर रहे हैं:

  • मान लीजिए कि एक हड्डी एक अनिश्चित स्थिति में है।
  • रोटेशन लागू करें
  • हड्डी में बाधाओं से अधिक है? यदि हां, तो इसे घुमाएं जहां इसे और अधिक

आपका कोड जो यूलर रोटेशन को क्लैंप करता है वह वह हिस्सा है जहां आप हड्डी को पीछे घुमाते हैं। हालांकि यह कोड मूल हड्डी रोटेशन को अनदेखा करता है ताकि आपको अजीब व्यवहार दिखाई दे, जैसे कि आप जो स्नैपिंग देख रहे हैं।

इस के साथ काम करने के लिए एक आसान तरीका के बजाय यह करने के लिए है:

  • मान एक हड्डी अबाधित स्थिति में है
  • रोटेशन
  • परीक्षण लागू करता है, तो हड्डी की कमी
  • यदि हाँ से अधिक है, हमें यह पता लगाने की जरूरत है कि बाधा आंदोलन बंद कर देती है।
    1. रोटेशन को रोकें, इसे
    2. पर लागू करें हड्डी से अधिक बाधाएं हैं? यदि हाँ 1
    3. पर जाएं, यदि नहीं, तो रोटेशन को रोकें, इसे आगे की दिशा में लागू करें। गोटो 2
  • रखें करने से आप अपनी बाधा के कुछ सहिष्णुता के भीतर हैं जब तक कोण कि

अब इस काम करेंगे, लेकिन क्योंकि आपके रोटेशन quarternions सभी कोणों पर लागू की जा रही है, रोटेशन जब किसी भी बंद हो जाएगा उन बाधाओं में से एक नेट है, भले ही स्वतंत्रता कुछ और हो।

यदि आप एक दूसरे से स्वतंत्र रूप से घूर्णन लागू करते हैं, तो आप बाधाओं का सम्मान करने के लिए अपने क्लैंपिंग या उपर्युक्त तकनीक का विश्वसनीय उपयोग करने में सक्षम होंगे, और अपने लक्ष्य के साथ बारीकी से घूमने में भी सक्षम होंगे। - -

+0

quaternions और Euler कोणों के बीच कनवर्ट करना इस समाधान को तोड़ने लगता है। मुझे यकीन नहीं है कि quaternions का उपयोग करते हुए स्वतंत्र रूप से रोटेशन कैसे लागू करें। – KTC

+0

संक्षिप्त उत्तर आप नहीं करते हैं। यदि आपको स्वतंत्र रूप से घूर्णन लागू करने की आवश्यकता है, तो आपके आंतरिक डेटा संरचनाओं को यूलर रोटेशन को अलग-अलग रखने के साथ-साथ उन रोटेशन को लागू करने के क्रम को भी रखना चाहिए। –

+0

मैं ऐसा करने में सक्षम नहीं होगा। मैं keyframes के बीच interpolate करने के लिए quaternions का उपयोग करना चाहता हूँ। – KTC

0

एक समस्या यह है यूलर कोण के साथ वहाँ ताकि आप आसानी से रोटेशन कि चिकनी कर रहे हैं का एक क्रम बना सकते हैं, एक ही रोटेशन का प्रतिनिधित्व करने के लिए कई तरीके हैं, लेकिन कोण कि रोटेशन का प्रतिनिधित्व करने के चारों ओर कूद सकता है। यदि कोण बाध्य सीमा के अंदर और बाहर कूदते हैं, तो आप प्रभावों को देखेंगे जैसे आप वर्णन कर रहे हैं।

कल्पना कीजिए कि केवल एक्स रोटेशन शामिल था, और आपने एक्स रोटेशन को 0 और 180 डिग्री के बीच में बाधा डाली थी। यह भी कल्पना करें कि क्वाटरनियन को यूलर कोणों में परिवर्तित करने वाला आपका कार्य -180 से 180 डिग्री तक कोण देता है।

फिर आप रोटेशन के इस क्रम है:

True rotation After conversion After constraint 
179    179     179 
180    180     180 
181    -179     0 

आप देख सकते हैं कि भले ही रोटेशन सुचारू रूप से बदल रहा है, परिणाम अचानक एक तरफ से दूसरे पर चला जाएगा, क्योंकि रूपांतरण कार्य करने के लिए मजबूर करता परिणाम एक निश्चित सीमा में प्रतिनिधित्व किया जाना चाहिए।

जब आप क्वाटरनियन को यूलर कोणों में परिवर्तित कर रहे हैं, तो पिछले परिणाम के निकटतम कोण खोजें। उदाहरण के लिए:

eCurrent = closestAngles(qCurrent.toEuler(),eCurrent); 
eConstrained = clampAngles(eCurrent,min,max); 

अगली बार के लिए eCurrent मूल्यों याद है, और अपने कंकाल को eConstrained रोटेशन लागू होते हैं।

+0

मुझे समझ में नहीं आता है। ऐसा लगता है कि आपने "निकटतम कोण" के संदर्भ में समस्या को फिर से लिखा है। – KTC

+0

बिंदु यह है कि जब आप यूलर कोणों में परिवर्तित होते हैं, तो आपको पिछले कोणों पर भी विचार करना होगा, ताकि आपके यूलर रोटेशन का प्रतिनिधित्व चिकनी हो। –

+0

ठीक है, मैं देखता हूं कि आपका क्या मतलब है। क्या आप वाकई स्वतंत्र रूप से प्रत्येक धुरी के लिए ऐसा करने के लिए मान्य हैं? मैंने कोशिश की और इसे कभी भी काम पर नहीं ला सका। इसने "कूद" को ठीक किया, लेकिन हड्डियां अभी भी अमान्य उन्मुखताओं में समाप्त हो गईं। मुझे लगता है कि यूलर और quaternions के बीच आगे और पीछे परिवर्तित करने के आसपास कोणों के अलावा अन्य समस्याएं हैं। – KTC

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