2011-07-17 20 views
10

मैं प्रोग्रामिंग स्टारक्राफ्ट 2 कस्टम मैप्स प्रोग्रामिंग कर रहा हूं और 3 डी में गणित के साथ कुछ proglems मिला है। वर्तमान में मैं एक्स, वाई और जेड (xyz वेक्टर सामान्यीकृत) द्वारा दिए गए मनमानी धुरी के चारों ओर एक बिंदु बनाने और घुमाने की कोशिश कर रहा हूं।एक मनमानी धुरी के आसपास परिपत्र रोटेशन

मैं बहुत कुछ करने की कोशिश कर रहा हूं और इंटरनेट पर बहुत सी चीजों के माध्यम से पढ़ रहा हूं, लेकिन मुझे यह नहीं पता कि यह सही तरीके से कैसे काम करता है।

point CP; 
fixed AXY; 
point D; 
point DnoZ; 
point DXY_Z; 
fixed AZ; 
fixed LXY; 
missile[Missile].Angle = (missile[Missile].Angle + missile[Missile].Acceleration) % 360.0; 
missile[Missile].Acceleration += missile[Missile].AirResistance; 
if (missile[Missile].Parent > -1) { 
    D = missile[missile[Missile].Parent].Direction; 
    DnoZ = Point(PointGetX(D),0.0); 
    DXY_Z = Normalize(Point(SquareRoot(PointDot(DnoZ,DnoZ)),PointGetHeight(D))); 
    AZ = MaxF(ACos(PointGetX(DXY_Z)),ASin(PointGetY(DXY_Z)))+missile[Missile].Angle; 
    DnoZ = Normalize(DnoZ); 
    AXY = MaxF(ACos(PointGetX(DnoZ)),ASin(PointGetY(DnoZ))); 
    CP = Point(Cos(AXY+90),Sin(AXY+90)); 
    LXY = SquareRoot(PointDot(CP,CP)); 
    if (LXY > 0) { 
     CP = PointMult(CP,Cos(AZ)/LXY); 
     PointSetHeight(CP,Sin(AZ)); 
    } else { 
     CP = Point3(0.0,0.0,1.0); 
    } 
} else { 
    CP = Point(Cos(missile[Missile].Angle),Sin(missile[Missile].Angle)); 
} 
missile[Missile].Direction = Normalize(CP); 
missile[Missile].Position = PointAdd(missile[Missile].Position,PointMult(missile[Missile].Direction,missile[Missile].Distance)); 

मैं बस नहीं कर सकते गणित के आसपास मेरे मन मिलती है: मेरे वर्तमान स्क्रिप्ट (आप शायद भाषा नहीं जानता, लेकिन यह कुछ भी नहीं विशेष है) घंटे (सही ढंग से काम नहीं करता है) के लिए सब कुछ तोड़ने का परिणाम है। यदि आप इसे सरल शब्दों में समझा सकते हैं जो सबसे अच्छा समाधान होगा, तो एक कोड स्नैप भी अच्छा होगा (लेकिन काफी उपयोगी नहीं है, क्योंकि मैं भविष्य में और 3 डी सामान करने की योजना बना रहा हूं)।

उत्तर

18

http://en.wikipedia.org/wiki/Rotation_matrix। अनुभाग Rotation matrix from axis and angle के तहत देखें। आपकी सुविधा के लिए, यहां आपको आवश्यक मैट्रिक्स है। यह थोड़ा बालों वाला है। थीटा कोण, और UX, UY है, और उज एक्स, वाई, और z सामान्यीकृत धुरी वेक्टर के घटक हैं

Here's the rotation matrix

आप मैट्रिक्स और वैक्टर समझ में नहीं आता है, तो वापस पोस्ट और मैं तुम्हारी मदद करूँगा।

+0

मुझे मैट्रिक्स भी मिला, मेरी समस्या यह है कि मुझे समझ में नहीं आता कि इसका उपयोग कैसे किया जाए। जो मैं समझ में नहीं आता वह यह है कि मैं उस बिंदु को कैसे बनाना चाहता हूं जिसे मैं घूमना चाहता हूं। आपकी सहायता के लिए धन्यवाद. – Alexander

+0

इसके बारे में बहुत कुछ सोचने के बाद, घूर्णन समस्या नहीं है, मुझे लगता है कि मैं घूर्णन को समझता हूं। मैं जो नहीं कर सकता वह मेरी धुरी के लिए लंबवत वेक्टर ढूंढ रहा है, कम से कम कोई भी जो धुरी के साथ घूमता नहीं है (अक्ष प्रत्येक 0.0625 सेकेंड बदलती है और मैं निरंतर दूरी के साथ घूर्णन चाहता हूं)। – Alexander

+0

यह अब काम करता है, मैं एक यूपी वेक्टर का उपयोग करता हूं जिसे मुझे प्रत्येक रोटेशन आदि पर गणना करना है। यदि आवश्यक हो तो इसकी गणना करने का कोई तरीका बेहतर होगा। – Alexander

9

ऐसे घूर्णन करने के लिए एक उपयोगी विधि उन्हें quaternions के साथ करना है। प्रैक्टिस में, मैंने उन्हें उपयोग करना आसान पाया है और Gimbal lock से बचने का अतिरिक्त बोनस है।

Here कि के माध्यम से एक अच्छा टहलने के बताते है कि कैसे और क्यों वे एक मनमाना अक्ष के बारे में रोटेशन के लिए उपयोग किया जाता है (यह उपयोगकर्ता के सवाल के जवाब है)। यह थोड़ा उच्च स्तर है और किसी ऐसे व्यक्ति के लिए अच्छा होगा जो विचार के लिए नया है, इसलिए मैं वहां से शुरू करने की सलाह देता हूं। लिंक जंग से बचने के लिए

अद्यतन

जुड़ा हुआ साइट से पाठ:

आप के रूप में कोई संदेह नहीं है पहले से ही निष्कर्ष निकाला है, रोटेशन धुरी मूल और पर एक बिंदु (a,b,c) के माध्यम से गुजर चारों ओर में इकाई क्षेत्र तीन आयाम एक रैखिक परिवर्तन है, और इसलिए मैट्रिक्स गुणा द्वारा प्रतिनिधित्व किया जा सकता है। हम इस मैट्रिक्स को निर्धारित करने के लिए विधि बहुत धीमी गति से देंगे, लेकिन सूत्र के की कॉम्पैक्टनेस की सराहना करने के लिए कुछ टिप्पणियों से शुरू करना बुद्धिमान होगा। तीन आयामों में

घुमाव नहीं बल्कि विशेष रैखिक परिवर्तनों क्योंकि वे वैक्टर की लंबाई की रक्षा और भी (जब दो वैक्टर घुमाया जाता है) वैक्टर के बीच कोण हैं, कम से कम नहीं। इस तरह के परिवर्तनों "ओर्थोगोनल" कहा जाता है और वे orthogonal मैट्रिक्स का प्रतिनिधित्व करती हैं:

M M' = I 

जहाँ हम आसानी से पक्षांतरित निरूपित '। दूसरे शब्दों में ऑर्थोगोनल मैट्रिक्स का स्थानांतरण इसके विपरीत है।

परिवर्तन को परिभाषित करने के लिए आवश्यक डेटा पर विचार करें। आपने पहले ही रोटेशन की धुरी के लिए नोटेशन दिया है, ai + bj + ck, आसानी से एक यूनिट वेक्टर माना जाता है। एकमात्र अन्य डाटाम रोटेशन के कोण है, जो अधिक प्राकृतिक चरित्र की कमी के लिए आर (रोटेशन के लिए?) द्वारा दर्शाया गया है और जिसे हम रेडियंस में दिए जाने के लिए मानेंगे।

अब रोटेशन वास्तव में थोड़ा भी ओर्थोगोनल परिवर्तनों के बीच विशेष कर रहे हैं, और वास्तव में वे भी "उन्मुखीकरण संरक्षण" होने की उनकी संपत्ति के आधार में विशेष orthogonal परिवर्तनों (या मैट्रिक्स) कहा जाता है। प्रतिबिंबों के साथ उनकी तुलना करें, जो भी लंबाई और कोण संरक्षण कर रहे हैं, और आप पाएंगे कि ज्यामितीय अभिविन्यास को संरक्षित करने की विशेषता (या "सौम्यता" यदि आप पसंद करते हैं) मैट्रिक्स के निर्धारक में संख्यात्मक समकक्ष है। एक रोटेशन के मैट्रिक्स में निर्धारक 1 है, जबकि प्रतिबिंब के मैट्रिक्स में निर्धारक -1 है। ऐसा लगता है कि दो रोटेशन के उत्पाद (या रचना) फिर से एक रोटेशन है, जो तथ्य यह है कि एक उत्पाद के निर्धारक निर्धारकों के उत्पाद (या में 1 एक रोटेशन के मामले) है के साथ सहमत हैं है।

अब हम चरण-दर-चरण दृष्टिकोण का वर्णन कर सकते हैं कि वांछित मैट्रिक्स का निर्माण कर सकता है (इससे पहले कि हम पूरी प्रक्रिया को शॉर्टकट करें और उत्तर पर जाएं!)। पहले एक कदम है जिसमें हम इकाई वेक्टर बारी बारी से विचार करें:

u = ai + bj + ck 

इतना है कि यह, "मानक" इकाई वैक्टर में से एक के साथ मेल खाता शायद कश्मीर (positve z- अक्ष)। अब हम जानते हैं कि जेड-अक्ष के चारों ओर घुमाने के लिए कैसे; यह, पर एक्स सामान्य 2x2 परिवर्तन कर की बात है y अकेले निर्देशांक:,

 cos(r) sin(r) 0 
M = -sin(r) cos(r) 0 
     0  0  1 

अंत में हम चाहते हैं कि प्रारंभिक रोटेशन कि यू ले लिया k करने के लिए "पूर्ववत करें" करने की जरूरत है जो आसान है क्योंकि के प्रतिलोम वह परिवर्तन है (हम याद) मैट्रिक्स ट्रांसपोज़ द्वारा प्रतिनिधित्व किया जाता है।

R' M R 

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

R' M R u = R' M k = R' k = u 

इसलिए यह वास्तव में अक्ष यू द्वारा परिभाषित के बारे में रोटेशन है।

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

तो, शॉर्टकट पर। यह पता चला जब सब धूल सुलझेगी कि रोटेशन के बीच गुणा इकाई quaternions के गुणन isomorphic को है। Quaternions, स्थिति में आप उन्हें पहले नहीं देखा है, जटिल संख्याओं के चार आयामी सामान्यीकरण की एक तरह कर रहे हैं।वे 1843 में विलियम हैमिल्टन द्वारा 'आविष्कार' थे:

[सर विलियम रोवान हैमिल्टन] http://www-gap.dcs.st-and.ac.uk/~history/Mathematicians/Hamilton.html

और आज के 3 डी ग्राफिक्स प्रोग्रामर अपने कर्ज में बहुत हैं।

 (q0² + q1² - q2² - q3²)  2(q1q2 - q0q3)   2(q1q3 + q0q2) 

Q =  2(q2q1 + q0q3)  (q0² - q1² + q2² - q3²)  2(q2q3 - q0q1) 

      2(q3q1 - q0q2)   2(q3q2 + q0q1)  (q0² - q1² - q2² + q3²) 

कि क्यू एक orthogonal मैट्रिक्स है सत्यापित करने के लिए, अर्थात्:

प्रत्येक इकाई में चार का समुदाय q = q0 + q1*i + q2*j + q3*k तो एक रोटेशन मैट्रिक्स परिभाषित करता है। Q Q' = I, में सार है कि क्यू की पंक्तियां एक ऑर्थोनॉर्मल आधार बनाती हैं।

(q0² + q1² - q2² - q3²)² + 4(q1q2 - q0q3)² + 4(q1q3 + q0q2)² 

    = (q0² + q1² - q2² - q3²)² + 4(q1q2)² + 4(q0q3)² + 4(q1q3)² + 4(q0q2)² 

    = (q0² + q1² + q2² + q3²)² 

    = 1 

और पहली दो पंक्तियों होना चाहिए डॉट उत्पाद शून्य:: तो, उदाहरण के लिए, पहली पंक्ति लंबाई 1 होना चाहिए

[ (q0² + q1² - q2² - q3²), 2(q1q2 - q0q3), 2(q1q3 + q0q2) ] 

    * [ 2(q2q1 + q0q3), (q0² - q1² + q2² - q3²), 2(q2q3 - q0q1) ] 

= 2(q0² + q1² - q2² - q3²)(q2q1 + q0q3) 

    + 2(q1q2 - q0q3)(q0² - q1² + q2² - q3²) 

    + 4(q1q3 + q0q2)(q2q3 - q0q1) 

= 4(q0²q1q2 + q1²q0q3 - q2²q0q3 - q3²q2q1) 

    + 4(q3²q1q2 - q1²q0q3 + q2²q0q3 - q0²q2q1) 

= 0 

यह भी है कि det(Q) = 1 सामान्य रूप में दिखाया जा सकता है, और इस प्रकार क्यू वास्तव में एक घूर्णन है।

लेकिन किनारों के आस-पास घूर्णन क्यू के आसपास है? और किस कोण से? खैर, दिए गए कोण r और इकाई वेक्टर:

u = ai + bj + ck 

के रूप में पहले, इसी चौका है:

q = cos(r/2) + sin(r/2) * u 

    = cos(r/2) + sin(r/2) ai + sin(r/2) bj + sin(r/2) ck 
इस प्रकार के साथ

:

q0 = cos(r/2), q1 = sin(r/2) a, q2 = sin(r/2) b, q3 = sin(r/2) c, 

हम वांछित संपत्ति प्राप्त करने में सक्षम हैं क्यू "फिक्स" द्वारा गुणा:

Q u = u 

लंबी हवादार बीजगणित के माध्यम से चिपकने की बजाय, चलिए एक साधारण उदाहरण करते हैं।

u = 0i + 0.6j + 0.8k हमारे यूनिट वेक्टर बनें और आर = पीआई रोटेशन के हमारे कोण हों।

फिर चौका है:

q = cos(pi/2) + sin(pi/2) * u 

    = 0 + 0i + 0.6j + 0.8k 

और रोटेशन मैट्रिक्स:

 -1  0  0 

Q =  0 -0.28 0.96 

     0 0.96 0.28 

इस ठोस मामले में यह है कि QQ '= मैं और det (क्यू) = 1 सत्यापित करने के लिए आसान है।

इसके अलावा हम गणना कि:

Q u = [ 0, -0.28*0.6 + 0.96*0.8, 0.96*0.6 + 0.28*0.8 ]' 

    = [ 0, 0.6, 0.8 ]' 

    = u 

यानी। यूनिट वेक्टर आप रोटेशन की धुरी को परिभाषित करता है क्योंकि यह क्यू द्वारा "निश्चित" है।

अंत में हम यह दर्शाते हैं कि रोटेशन के कोण कैसे क्यू जिस दिशा यू करने के लिए खड़ा है सकारात्मक x- अक्ष, की में इकाई वेक्टर पर कार्य करता है पर विचार करके अनुकरणीय (या 180 डिग्री) है:

i + 0j + 0k, or as a vector, [ 1, 0, 0 ]' 

फिर Q [ 1, 0, 0 ]' = [-1, 0, 0 ]' जो आपके बारे में कोण pi के माध्यम से [1, 0, 0 ] 'का घूर्णन है।

[का प्रतिनिधित्व करते हुए 3 डी रोटेशन] http://gandalf-library.sourceforge.net/tutorial/report/node125.html

:

quaternions से रोटेशन के इस प्रतिनिधित्व और प्रतिनिधित्व के कुछ अतिरिक्त तरीकों (और वे क्या अच्छा के लिए कर रहे हैं) के लिए एक संदर्भ के रूप में, यहाँ विवरण देखने के

सारांश

रेडियंस और इकाई वेक्टर यू में

को देखते हुए कोण r = + बी.जे. + सी.के. या [क, ख, ग] 'एअर इंडिया, निर्धारित करें:

q0 = cos(r/2), q1 = sin(r/2) a, q2 = sin(r/2) b, q3 = sin(r/2) c 

और इन मूल्यों से रोटेशन मैट्रिक्स का निर्माण:

 (q0² + q1² - q2² - q3²)  2(q1q2 - q0q3)   2(q1q3 + q0q2) 

Q =  2(q2q1 + q0q3)  (q0² - q1² + q2² - q3²)  2(q2q3 - q0q1) 

      2(q3q1 - q0q2)   2(q3q2 + q0q1)  (q0² - q1² - q2² + q3²) 

गुणा क्यू द्वारा तब इच्छित रोटेशन प्रभाव, और विशेष रूप से:

Q u = u 
2

यहाँ तुम क्या किसी के बारे में बारी बारी से करने का उपयोग कर सकते है धुरी, यह एक्स, वाई या जेड हो। आरएक्स, राय और आरजे क्रमशः एसीएस एक्स, वाई, जेड के बारे में घूर्णन दर्शाते हैं।

enter image description here

+4

वह छवि [यहां] से है (http://en.wikipedia.org/wiki/Rotation_matrix # बेसिक_रोटेशन), है ना? आपको शायद इसका हवाला देना चाहिए। –

4

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

मूल बिंदु को ऑफ़सेट करें।

Point of Rotation = (X1, Y1, Z1) 
Point Location = (X1+A, Y1+B, Z1+C) 

(Point Location - Point of Rotation) = (A, B, C). 

जेड एक्सिस के बारे में रोटेशन निष्पादित करें।

A' = A*cos ZAngle - B*sin ZAngle 
    B' = A*sin ZAngle + B*cos ZAngle 
    C' = C. 

अगला, वाई एक्सिस के बारे में घूर्णन करें।

C'' = C'*cos YAngle - A'*sin YAngle 
    A'' = C'*sin YAngle + A'*cos YAngle 
    B'' = B' 

अब एक्स एक्सिस के बारे में अंतिम रोटेशन करें।

B''' = B''*cos XAngle - C''*sin XAngle 
    C''' = B''*sin XAngle + C''*cos XAngle 
    A''' = A'' 

अंत में, इन मानों को रोटेशन के मूल बिंदु पर वापस जोड़ें।

Rotated Point = (X1+A''', Y1+B''', Z1+C'''); 

मैं इस link बहुत उपयोगी हो पाया। यह एक्स, वाई और जेड अक्ष के बारे में व्यक्तिगत घूर्णन करने के तरीके को परिभाषित करता है।

गणित के अनुसार, तुम इतनी तरह आपरेशन के सेट को परिभाषित कर सकते हैं:

enter image description here

-2

अजगर कार्यान्वयन, मेरे लिए काम किया।

cos180=-1 
sin180=0 

rotmatrix=np.zeros((3,3)) 
rotmatrix[0][0]=cos180 + rotaxis[0]**2 * (1-cos180) 
rotmatrix[0][1]=rotaxis[0]*rotaxis[1] * (1-cos180) - rotaxis[2] * sin180 
rotmatrix[0][2]=rotaxis[0]*rotaxis[2] * (1-cos180) + rotaxis[1] * sin180 

rotmatrix[1][0]=rotaxis[1]*rotaxis[0] * (1-cos180) + rotaxis[2] * sin180 
rotmatrix[1][1]=cos180 + rotaxis[1]**2 * (1-cos180) 
rotmatrix[1][2]=rotaxis[1]*rotaxis[2] * (1-cos180) - rotaxis[0] * sin180 

rotmatrix[2][0]=rotaxis[2]*rotaxis[0] * (1-cos180) - rotaxis[1] * sin180 
rotmatrix[2][1]=rotaxis[2]*rotaxis[1] * (1-cos180) + rotaxis[0] * sin180 
rotmatrix[2][2]=cos180 + rotaxis[2] ** 2 * (1-cos180) 
संबंधित मुद्दे