क्या कोई (कारणों के कारण) को समझा सकता है कि कोलम बनाम पंक्ति के निहितार्थ गुणा / संक्षेपण में प्रमुख हैं?


11

मैं यह जानने की कोशिश कर रहा हूं कि मैट्रिस के लिए दो मानकों के बारे में मेरी उलझन के कारण दृश्य और प्रोजेक्शन मैट्रीक का निर्माण कैसे किया जा सकता है, और मेरे कार्यान्वयन में कठिनाइयों तक पहुंच सकता है।
मुझे पता है कि एक मैट्रिक्स को कैसे गुणा करना है, और मैं देख सकता हूं कि गुणा से पहले ट्रांसपोज़ करने से परिणाम पूरी तरह से बदल जाएगा, इसलिए एक अलग क्रम में गुणा करने की आवश्यकता है।

हालांकि मुझे समझ नहीं आ रहा है कि व्हाट्स का मतलब केवल 'नोटेशनल कन्वेंशन' से है - यहां और यहां के लेखों से लेखक यह दावा करते हैं कि इससे कोई फर्क नहीं पड़ता कि मैट्रिक्स कैसे स्टोर किया जाता है, या GPU पर स्थानांतरित किया जाता है, लेकिन दूसरे पर पृष्ठ जो मैट्रिक्स स्पष्ट रूप से इसके समकक्ष नहीं है कि इसे पंक्ति-प्रमुख के लिए मेमोरी में कैसे रखा जाएगा; और अगर मैं अपने कार्यक्रम में एक आबादी वाले मैट्रिक्स को देखता हूं तो मैं अनुवाद घटकों को 4 वें, 8 वें और 12 वें तत्वों में देखता हूं।

मान लीजिये:

"स्तंभ-प्रमुख मैट्रिसेस के साथ पोस्ट-गुणा करना, पंक्ति-प्रमुख मैट्रिसेस के साथ पूर्व-गुणा करने के समान परिणाम उत्पन्न करता है।"

कोड के निम्नलिखित स्निपेट में क्यों:

        Matrix4 r = t3 * t2 * t1;
        Matrix4 r2 = t1.Transpose() * t2.Transpose() * t3.Transpose();

R! = R2 और pos3 क्यों करता है! = Pos :

        Vector4 pos = wvpM * new Vector4(0f, 15f, 15f, 1);
        Vector4 pos3 = wvpM.Transpose() * new Vector4(0f, 15f, 15f, 1);

क्या गुणन प्रक्रिया इस आधार पर बदलती है कि क्या मैट्रीस पंक्ति या स्तंभ प्रमुख हैं , या यह सिर्फ एक आदेश है (समकक्ष प्रभाव के लिए?)

एक बात जो इसे स्पष्ट करने में मदद नहीं कर रही है, वह यह है कि जब डायरेक्टएक्स को प्रदान किया जाता है, तो मेरे कॉलम प्रमुख WVP मैट्रिक्स का उपयोग एचएलएसएल कॉल के साथ कोने को बदलने के लिए सफलतापूर्वक किया जाता है: mul (वेक्टर, मैट्रिक्स) जिसके परिणामस्वरूप वेक्टर का इलाज किया जाना चाहिए। पंक्ति-प्रमुख , इसलिए मेरे गणित पुस्तकालय द्वारा प्रदान किए गए स्तंभ प्रमुख मैट्रिक्स कैसे काम कर सकते हैं?



जवाबों:


11

यदि मैं अपने कार्यक्रम में एक आबादी वाले मैट्रिक्स को देखता हूं तो मैं अनुवाद घटकों को 4 वें, 8 वें और 12 वें तत्वों में देखता हूं।

शुरू करने से पहले, यह समझना महत्वपूर्ण है: इसका मतलब है कि आपके मैट्रिस पंक्ति प्रमुख हैं । इसलिए, आप इस प्रश्न का उत्तर देते हैं:

मेरे स्तंभ प्रमुख WVP मैट्रिक्स का उपयोग एचएलएसएल कॉल के साथ कोने को बदलने के लिए सफलतापूर्वक किया जाता है: मूल (वेक्टर, मैट्रिक्स) जिसके परिणामस्वरूप वेक्टर को पंक्ति-प्रमुख के रूप में माना जाना चाहिए, इसलिए मेरे गणित पुस्तकालय द्वारा प्रदान किए गए कॉलम प्रमुख मैट्रिक्स कैसे काम कर सकते हैं?

काफी सरल है: आपके मैट्रिस पंक्ति-प्रमुख हैं।

इतने सारे लोग पंक्ति-प्रमुख या ट्रांसपोज़्ड मैट्रिस का उपयोग करते हैं, कि वे भूल जाते हैं कि मैट्रिस स्वाभाविक रूप से उस तरह से उन्मुख नहीं हैं। इसलिए वे इस प्रकार एक अनुवाद मैट्रिक्स देखते हैं:

1 0 0 0
0 1 0 0
0 0 1 0
x y z 1

यह एक ट्रांसपोसड ट्रांसलेशन मैट्रिक्स है । ऐसा नहीं है कि एक सामान्य अनुवाद मैट्रिक्स कैसा दिखता है। अनुवाद 4 में चला जाता है स्तंभ , नहीं चौथी पंक्ति। कभी-कभी, आप इसे पाठ्यपुस्तकों में भी देखते हैं, जो पूरी तरह से कचरा है।

यह जानना आसान है कि एक सरणी में एक मैट्रिक्स पंक्ति या स्तंभ-प्रमुख है या नहीं। यदि यह पंक्ति-प्रमुख है, तो अनुवाद 3, 7 और 11 वें सूचक में संग्रहीत किया जाता है। यदि यह स्तंभ-प्रधान है, तो अनुवाद 12, 13 और 14 वें सूचक में संग्रहीत किया जाता है। पाठ्यक्रम के शून्य-आधार सूचकांक।

जब आप वास्तव में पंक्ति-प्रमुख लोगों का उपयोग कर रहे हैं तो स्तंभ-प्रमुख मैट्रिक्स का उपयोग कर रहे हैं यह विश्वास करने से आपका भ्रम उपजा है।

यह कथन कि पंक्ति बनाम स्तंभ प्रमुख केवल एक उल्लेखनीय सम्मेलन है, पूरी तरह सत्य है। कन्वेंशन की परवाह किए बिना मैट्रिक्स गुणा और मैट्रिक्स / वेक्टर गुणा के मैकेनिक्स समान हैं।

परिणामों में क्या परिवर्तन होता है।

सब के बाद एक 4x4 मैट्रिक्स संख्याओं का सिर्फ 4x4 ग्रिड है। इसमें समन्वय प्रणाली के बदलाव का उल्लेख नहीं है । हालांकि, एक बार जब आप किसी विशेष मैट्रिक्स को अर्थ प्रदान करते हैं, तो आपको अब यह जानना होगा कि इसमें क्या संग्रहीत है और इसका उपयोग कैसे किया जाए।

अनुवाद मैट्रिक्स लें जो मैंने आपको ऊपर दिखाया है। यह एक वैध मैट्रिक्स है। आप float[16]दो तरीकों में से एक में उस मैट्रिक्स को स्टोर कर सकते हैं:

float row_major_t[16] =    {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1};
float column_major_t[16] = {1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1};

हालाँकि, मैंने कहा कि यह अनुवाद मैट्रिक्स गलत है, क्योंकि अनुवाद गलत जगह पर है। मैंने विशेष रूप से कहा कि यह ट्रांसलेशन मैट्रिसेस को कैसे बनाया जाए, इसके लिए मानक सम्मेलन के सापेक्ष ट्रांसपोज़ किया जाता है, जो इस तरह दिखना चाहिए:

1 0 0 x
0 1 0 y
0 0 1 z
0 0 0 1

आइए देखें कि ये कैसे संग्रहीत हैं:

float row_major[16] =    {1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1};
float column_major[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1};

सूचना है कि column_majorहै ठीक उसी रूप में row_major_t। इसलिए, यदि हम एक उचित अनुवाद मैट्रिक्स लेते हैं , और इसे स्तंभ-प्रमुख के रूप में संग्रहीत करते हैं, तो यह उस मैट्रिक्स को स्थानांतरित करने और इसे पंक्ति-प्रमुख के रूप में संग्रहीत करने के समान है।

इसका मतलब केवल एक संवैधानिक सम्मेलन होने से है। सम्मेलनों के वास्तव में दो सेट हैं: मेमोरी स्टोरेज और ट्रांसपोज़िशन। मेमोरी संग्रहण कॉलम बनाम पंक्ति प्रमुख है, जबकि ट्रांसपोज़ेशन सामान्य बनाम ट्रांसपोज़्ड है।

यदि आपके पास एक मैट्रिक्स है जो पंक्ति-प्रमुख क्रम में उत्पन्न हुआ था, तो आप उस मैट्रिक्स के स्तंभ-प्रमुख समकक्ष को स्थानांतरित करके समान प्रभाव प्राप्त कर सकते हैं। और इसके विपरीत।

मैट्रिक्स गुणन केवल एक ही तरीके से किया जा सकता है: दो मैट्रिक्स दिए गए, एक विशिष्ट क्रम में, आप कुछ मानों को एक साथ गुणा करते हैं और परिणामों को संग्रहीत करते हैं। अब, A*B != B*Aलेकिन वास्तविक स्रोत कोड के लिए कोड A*Bके समान है B*A। वे दोनों आउटपुट की गणना करने के लिए समान कोड चलाते हैं।

मैट्रिक्स गुणन कोड परवाह नहीं करता है कि क्या कॉलम-प्रमुख या पंक्ति-प्रमुख क्रम में संग्रहीत किए जाने वाले मैट्रिसेस होते हैं।

एक ही नहीं कर सकते वेक्टर / मैट्रिक्स गुणन के लिए कहा जा सकता है। और यहाँ क्यों है।

वेक्टर / मैट्रिक्स गुणन एक झूठ है; यह नहीं किया जा सकता है। हालाँकि, आप एक मैट्रिक्स को दूसरे मैट्रिक्स से गुणा कर सकते हैं । इसलिए यदि आप एक वेक्टर का दिखावा करते हैं कि यह एक मैट्रिक्स है, तो आप वेक्टर / मैट्रिक्स गुणा को प्रभावी ढंग से कर सकते हैं, बस मैट्रिक्स / मैट्रिक्स गुणा करके।

4D वेक्टर को कॉलम-वेक्टर या पंक्ति-वेक्टर माना जा सकता है। यही है, एक 4D वेक्टर को 4x1 मैट्रिक्स के रूप में सोचा जा सकता है (याद रखें: मैट्रिक्स नोटेशन में, पंक्ति गणना पहले आती है) या 1x4 मैट्रिक्स।

लेकिन यहाँ एक बात है: दो मैट्रिक्स ए और बी को देखते हुए, A*Bकेवल तभी परिभाषित किया जाता है यदि ए के कॉलम की संख्या बी की पंक्तियों की संख्या के समान है, इसलिए यदि ए हमारी 4x4 मैट्रिक्स है, तो बी को 4 पंक्तियों के साथ एक मैट्रिक्स होना चाहिए। इस में। इसलिए, आप प्रदर्शन नहीं कर सकते A*x, जहां x एक पंक्ति-वेक्टर है । इसी तरह, आप प्रदर्शन नहीं कर सकते x*Aजहां x एक कॉलम-वेक्टर है।

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

हमें परिभाषित करें, किसी भी 4D वेक्टर x के लिए, निम्नलिखित। Cका स्तंभ-वेक्टर मैट्रिक्स रूप होगा x, और Rपंक्ति-वेक्टर मैट्रिक्स रूप होगा x। इसे देखते हुए, किसी भी 4x4 मैट्रिक्स ए के लिए, A*Cकॉलम-वेक्टर द्वारा मैट्रिक्स को गुणा करने का प्रतिनिधित्व करता है x। और A R*Aसे पंक्ति-वेक्टर xको गुणा करने वाले मैट्रिक्स का प्रतिनिधित्व करता है।

लेकिन अगर हम सख्त मैट्रिक्स गणित का उपयोग करके इसे देखते हैं, तो हम देखते हैं कि ये समान नहीं हैं । R*A नहीं कर सकते हैं के रूप में ही A*C। ऐसा इसलिए है क्योंकि एक पंक्ति-वेक्टर स्तंभ-वेक्टर के समान नहीं है। वे समान मैट्रिक्स नहीं हैं, इसलिए वे समान परिणाम नहीं देते हैं।

हालांकि, वे एक तरह से संबंधित हैं। ऐसा नहीं है कि सच है R != C। हालांकि, यह भी सच है कि , जहां टी ट्रांसपोज़ेशन ऑपरेशन है। दो मातृकाएँ एक-दूसरे के प्रतिरूप हैं।R = CT

यहां एक मजेदार तथ्य है। चूंकि वैक्टर को मैट्रिस के रूप में माना जाता है, इसलिए उनके पास एक कॉलम बनाम पंक्ति-प्रमुख भंडारण प्रश्न है। समस्या यह है कि वे दोनों एक जैसे दिखते हैं । फ़्लोट्स की सरणी समान है, इसलिए आप डेटा को देखकर केवल R और C के बीच अंतर नहीं बता सकते। अंतर बताने का एकमात्र तरीका यह है कि उनका उपयोग कैसे किया जाता है।

यदि आपके पास कोई दो मैट्रिसेस ए और बी हैं, और ए को पंक्ति-प्रमुख और बी को कॉलम-प्रमुख के रूप में संग्रहीत किया जाता है, तो उन्हें गुणा करना पूरी तरह से व्यर्थ है । परिणामस्वरूप आपको बकवास लगता है। असल में ऐसा नहीं है। गणितीय रूप से, जो आपको मिलता है वह करने के बराबर है । या ; वे गणितीय रूप से समान हैं।AT*BA*BT

इसलिए, मैट्रिक्स गुणन केवल तभी समझ में आता है जब दो मैट्रिक्स (और याद रखें: वेक्टर / मैट्रिक्स गुणन सिर्फ मैट्रिक्स गुणन है) एक ही प्रमुख क्रम में संग्रहीत होते हैं।

तो, एक वेक्टर कॉलम-प्रमुख या पंक्ति-प्रमुख है? यह दोनों और न ही है, जैसा कि पहले कहा गया है। यह कॉलम प्रमुख है केवल जब इसे कॉलम मैट्रिक्स के रूप में उपयोग किया जाता है, और यह पंक्ति प्रमुख होता है जब इसे पंक्ति मैट्रिक्स के रूप में उपयोग किया जाता है।

इसलिए, यदि आपके पास एक मैट्रिक्स ए है जो कॉलम प्रमुख है, तो x*Aइसका मतलब है ... कुछ भी नहीं। खैर, फिर से, इसका मतलब है , लेकिन यह वह नहीं है जो आप वास्तव में चाहते थे। इसी तरह, यदि पंक्ति प्रमुख है, तो गुणा गुणन करता है ।x*ATA*xA

इसलिए, वेक्टर / मैट्रिक्स गुणन के आदेश करता है डेटा के अपने प्रमुख आदेश के आधार पर, परिवर्तन (और आप स्थानांतरित मैट्रिक्स उपयोग कर रहे हैं)।

कोड के निम्नलिखित स्निपेट में r क्यों होता है! = R2

क्योंकि आपका कोड टूट गया है और छोटी गाड़ी है। गणित के अनुसार, । यदि आपको यह परिणाम नहीं मिलता है, तो या तो आपकी समानता परीक्षण गलत है (फ्लोटिंग-पॉइंट सटीक मुद्दे) या आपका मैट्रिक्स गुणन कोड टूट गया है।A * (B * C) == (CT * BT) * AT

pos3 क्यों है! = pos के लिए

क्योंकि इसका कोई मतलब नहीं है। सच होने का एकमात्र तरीका होगा यदि । और यह केवल सममित मैट्रिक्स का सच है।A * t == AT * tA == AT


@ नाइकोल, सब कुछ अब क्लिक करना शुरू कर रहा है। जो कुछ मैं देख रहा था और जो मैंने सोचा था कि मुझे होना चाहिए, के बीच एक डिस्कनेक्ट के कारण भ्रम था, क्योंकि मेरी लाइब्रेरी (Axiom से ली गई) कॉलम-मेजर घोषित करती है (और सभी गुणा आदेश आदि इसके अनुरूप हैं) फिर भी मेमोरी लेआउट पंक्ति है -मेजर (अनुवाद सूचकांकों द्वारा और तथ्य एचएलएसएल गैर-ट्रांसपोज्ड मैट्रिक्स का उपयोग करके सही ढंग से काम करता है); मैं अब देखता हूं कि यह संघर्ष में कैसे नहीं है। आपका बहुत बहुत धन्यवाद!
sebf

2
मैंने आपको लगभग "जैसे कि सामान्य अनुवाद मैट्रिक्स जैसा दिखता है" और "जो कि कचरा है" कहा है। फिर आप आगे बढ़ते हैं और अच्छी तरह से समझाते हैं कि वे पूरी तरह से बराबर क्यों हैं और इसलिए न तो अधिक "प्राकृतिक" है, फिर अन्य। आप शुरुआत से ही उस छोटी सी बकवास को क्यों नहीं हटाते? आपका बाकी जवाब वास्तव में अच्छा नहीं है। (इसके अलावा, रुचि के लिए: steve.hollasch.net/cgindex/math/matrix/column-vec.html )
imre

2
@imre: क्योंकि यह बकवास नहीं है। कन्वेंशन महत्वपूर्ण हैं क्योंकि यह दो सम्मेलनों के लिए भ्रमित है। गणितज्ञों ने एक लंबे समय पहले मैट्रिस के लिए सम्मेलन में बस गए । "ट्रांसपोज़्ड मैट्रिसेस" (नाम दिया गया है क्योंकि वे मानक से ट्रांसपोज़्ड हैं) उस कन्वेंशन का उल्लंघन हैं। चूंकि वे समान हैं, वे उपयोगकर्ता को कोई वास्तविक लाभ नहीं देते हैं। और चूंकि वे अलग हैं और उनका दुरुपयोग किया जा सकता है, इसलिए यह भ्रम पैदा करता है। या इसे दूसरे तरीके से रखने के लिए, यदि ट्रांसपोटेड मैट्रिसेस मौजूद नहीं थे, तो ओपी ने कभी यह नहीं पूछा होगा। और इसलिए, यह वैकल्पिक सम्मेलन भ्रम पैदा करता है।
निकोल बोलस

1
@ निकोल: 12-13-14 में एक मैट्रिक्स का अनुवाद अभी भी पंक्ति-प्रमुख हो सकता है - अगर हम इसके साथ पंक्ति वैक्टर का उपयोग करते हैं (और वीएम के रूप में गुणा करें)। डायरेक्टएक्स देखें। या इसे कॉलम वैक्टर के रूप में देखा जा सकता है, जिसका उपयोग कॉलम वैक्टर (एमवी, ओपनजीएल) के साथ किया जाता है। यह वास्तव में एक ही है। इसके विपरीत, यदि किसी मैट्रिक्स का 3-7-11 में अनुवाद है, तो इसे कॉलम वैक्टर के साथ या तो पंक्ति-प्रमुख मैट्रिक्स के रूप में देखा जा सकता है, या पंक्ति वैक्टर के साथ स्तंभ-प्रमुख। 12-13-14 संस्करण वास्तव में अधिक सामान्य है, लेकिन मेरी राय में 1) यह वास्तव में एक मानक नहीं है, और 2) इसे कॉलम-मेजर कहना भ्रामक हो सकता है, क्योंकि यह आवश्यक नहीं है।
imre

1
@imre: यह मानक है। किसी भी वास्तविक प्रशिक्षित गणितज्ञ से पूछें कि अनुवाद कहां जाता है, और वे आपको बताएंगे कि यह चौथे कॉलम में जाता है। गणितज्ञों ने मैट्रिस का आविष्कार किया ; वे वही हैं जो सम्मेलनों की स्थापना करते हैं।
निकोल बोलस

3

यहां काम पर सम्मेलन के दो अलग-अलग विकल्प हैं। एक यह है कि क्या आप पंक्ति वैक्टर या स्तंभ वैक्टर का उपयोग करते हैं, और इन सम्मेलनों के लिए मैट्रिस एक दूसरे के संक्रमण हैं।

दूसरा यह है कि क्या आप मैट्रिसेस को पंक्ति-प्रमुख क्रम या स्तंभ-प्रमुख क्रम में मेमोरी में संग्रहीत करते हैं । ध्यान दें कि "पंक्ति-प्रमुख" और "स्तंभ-प्रमुख" पंक्ति-वेक्टर / स्तंभ-वेक्टर सम्मेलन पर चर्चा करने के लिए सही शब्द नहीं हैं ... हालांकि कई लोग उन्हें इस तरह से दुरुपयोग करते हैं। पंक्ति-प्रमुख और स्तंभ-प्रमुख मेमोरी लेआउट एक स्थानान्तरण द्वारा भिन्न होते हैं, भी।

OpenGL एक कॉलम वेक्टर कन्वेंशन और कॉलम-मेजर स्टोरेज ऑर्डर का उपयोग करता है, और D3D एक पंक्ति वेक्टर कन्वेंशन और रो-मेजर स्टोरेज ऑर्डर (अच्छी तरह से - कम से कम D3DX, गणित पुस्तकालय, करता है) का उपयोग करता है, इसलिए दो ट्रांस्फ़ॉर्म रद्द कर देते हैं और यह निकल जाता है। OpenGL और D3D दोनों के लिए समान मेमोरी लेआउट काम करता है। अर्थात्, मेमोरी में क्रमिक रूप से संग्रहीत 16 फ़्लोट्स की समान सूची दोनों एपीआई में एक ही तरह से काम करेगी।

हो सकता है कि लोगों के कहने का यह मतलब हो कि "मैट्रिक्स को कैसे संग्रहीत किया जाए, या GPU में स्थानांतरित किया जाए, इससे कोई फर्क नहीं पड़ता है"।

आपके कोड स्निपेट के रूप में, r! = R2 क्योंकि किसी उत्पाद के हस्तांतरण का नियम है (ABC) ^ T = C ^ TB ^ TA ^ T। ट्रांसपोज़िशन ऑर्डर के एक रिवेरल के साथ गुणा से अधिक वितरित करता है। तो आपके मामले में आपको r.Transpose () == r2, r r == r2 मिलना चाहिए।

इसी तरह, pos! = Pos3 क्योंकि आपने ट्रांसपोज़ किया है लेकिन गुणा क्रम को उल्टा नहीं किया है। आपको wpvM * localPos == localPos * wvpM.Tranpose () मिलना चाहिए। वेक्टर को स्वचालित रूप से एक पंक्ति वेक्टर के रूप में व्याख्या की जाती है जब मैट्रिक्स के बाईं ओर गुणा किया जाता है, और मैट्रिक्स के दाईं ओर गुणा होने पर कॉलम वेक्टर के रूप में। इसके अलावा, इस बात में कोई बदलाव नहीं है कि गुणन कैसे किया जाता है।

अंत में, फिर से: "मेरे कॉलम प्रमुख WVP मैट्रिक्स का उपयोग एचएलएसएल कॉल के साथ कोने को बदलने के लिए सफलतापूर्वक किया जाता है: mul (वेक्टर, मैट्रिक्स)," मैं इस बारे में अनिश्चित हूं, लेकिन शायद भ्रम / बग के कारण मैट्रिक्स से बाहर आ गया है गणित पुस्तकालय पहले से ही स्थानांतरित कर दिया गया।


1

3 डी ग्राफिक्स में आप वेक्टर और पॉइंट दोनों को बदलने के लिए मैट्रिक्स का उपयोग करते हैं। इस तथ्य को ध्यान में रखते हुए कि आप अनुवाद मैट्रिक्स के बारे में बात कर रहे हैं, मैं केवल बिंदुओं के बारे में बात करूँगा (आप मैट्रिक्स के साथ वेक्टर का अनुवाद नहीं कर सकते, या, यह बेहतर कह सकते हैं, आप कर सकते हैं लेकिन आप उसी वेक्टर को प्राप्त करेंगे)।

में आव्यूह गुणन पहले मैट्रिक्स के स्तंभ की संख्या दूसरा एक (यदि आप एक MXK के लिए anxm मैट्रिक्स गुणा कर सकते हैं) की पंक्ति की संख्या के बराबर होना चाहिए।

एक बिंदु (या एक वेक्टर) 3 घटकों (x, y, z) द्वारा दर्शाया जाता है और इसे एक पंक्ति या स्तंभ की तरह माना जा सकता है:

कोलम (आयाम 3 एक्स 1):

| X |

| Y |

| Z |

या

पंक्ति (आयाम 1 एक्स 3):

| एक्स, वाई, जेड |

आप पसंदीदा सम्मेलन चुन सकते हैं, यह सिर्फ एक सम्मेलन है। चलिए इसे T ट्रांसलेशन मैट्रिक्स कहते हैं। यदि आप पहले कन्वेंशन का चयन करते हैं, तो एक मैट्रिक्स के लिए एक बिंदु पी को गुणा करने के लिए आपको एक पोस्ट गुणा का उपयोग करने की आवश्यकता है:

T * v (आयाम 3x3 * 3x1)

अन्यथा:

v * T (आयाम 1x3 * 3x3)

लेखक यह दावा करते हैं कि यह इस बात से कोई अंतर नहीं रखता है कि मैट्रिक्स को कैसे संग्रहीत किया जाए, या GPU पर स्थानांतरित किया जाए

यदि आप हमेशा एक ही सम्मेलन का उपयोग करते हैं तो इससे कोई फर्क नहीं पड़ता। इसका मतलब यह नहीं है कि विभिन्न सम्मेलन के मैट्रिक्स में एक ही मेमोरी प्रतिनिधित्व होगा, लेकिन यह कि 2 अलग-अलग सम्मेलनों के साथ एक बिंदु को बदलना आपको समान रूप से परिवर्तित बिंदु प्राप्त होगा:

पी 2 = बी * ए * पी 1; // पहला सम्मेलन

p3 = p1 * A * B; // दूसरा सम्मेलन

पी 2 == पी 3;


1

मैं देख रहा हूं कि 4, 8 और 12 वें तत्वों पर अनुवाद करने वाले घटक का मतलब है कि आपके मैट्रिस "गलत" हैं।

अनुवाद घटक हमेशा परिवर्तन मैट्रिक्स के # 13, # 14 और # 15 के रूप में निर्दिष्ट किए जाते हैं ( तत्व # 1 के रूप में सरणी के बहुत पहले तत्व की गिनती )।

एक पंक्ति प्रमुख परिवर्तन मैट्रिक्स इस तरह दिखता है:

[ 2 2 2 1 ]   R00 R01 R02 0  
              R10 R11 R12 0 
              R20 R21 R22 0 
              t.x t.y t.z 1 

एक स्तंभ प्रमुख परिवर्तन मैट्रिक्स इस तरह दिखता है:

 R00 R01 R02 t.x   2  
 R10 R11 R12 t.y   2 
 R20 R21 R22 t.z   2 
  0   0   0   1    1 

पंक्ति के प्रमुख मेट्रिस को पंक्तियों के नीचे जाने के लिए निर्दिष्ट किया जाता है

ऊपर पंक्ति प्रमुख मैट्रिक्स को एक रैखिक सरणी के रूप में घोषित करते हुए, मैं लिखूंगा:

ROW_MAJOR = { R00, R01, R02, 0,  // row 1 // very intuitive
              R10, R11, R12, 0,  // row 2
              R20, R21, R22, 0,  // row 3
              t.x, t.y, t.z, 1 } ; // row 4

जो बहुत स्वाभाविक लगता है। क्योंकि ध्यान दें, अंग्रेजी में "पंक्ति-प्रमुख" लिखा गया है - मैट्रिक्स पाठ में ऊपर दिखाई देता है जैसे कि यह गणित में होगा।

और यहाँ भ्रम की बात है।

स्तंभ के प्रमुख स्तंभ स्तंभों के नीचे जाते हुए निर्दिष्ट किए जाते हैं

इसका मतलब है कि कॉलम के प्रमुख परिवर्तन मैट्रिक्स को कोड में एक रैखिक सरणी के रूप में निर्दिष्ट करना है, आपको लिखना होगा:

    COLUMN_MAJOR = {R00, R10, R20, 0, // COLUMN # 1 // बहुत खाली और सहज
                     R01, R11, R21, 0,
                     R02, R12, R22, 0,
                     tx, ty, tz, 1};

ध्यान दें यह पूरी तरह से काउंटर-सहज ज्ञान युक्त है !! एक स्तंभ प्रमुख मैट्रिक्स में एक रैखिक सरणी को प्रारंभ करते समय स्तंभों को निर्दिष्ट किया जाता है , इसलिए पहली पंक्ति

COLUMN_MAJOR = { R00, R10, R20, 0,

मैट्रिक्स का पहला कॉलम निर्दिष्ट करता है :

 R00
 R10
 R20
  0 

और पहली पंक्ति नहीं , क्योंकि पाठ का सरल लेआउट आपको विश्वास होगा। जब आप इसे कोड में देखते हैं, तो आपको एक कॉलम प्रमुख मैट्रिक्स को मानसिक रूप से स्थानांतरित करना होगा, क्योंकि पहले निर्दिष्ट 4 तत्व वास्तव में पहले कॉलम का वर्णन करते हैं। मुझे लगता है यही कारण है कि बहुत से लोग कोड में पंक्ति-प्रमुख मैट्रीस को पसंद करते हैं (GO DIRECT3D) - खांसी। "

तो, अनुवाद घटक हमेशा रैखिक सरणी सूचक # 13, # 14, और # 15 (जहां पहला तत्व # 1 है) पर हैं, भले ही आप पंक्ति प्रमुख या स्तंभ प्रमुख मैट्रिक्स का उपयोग कर रहे हों।

आपके कोड के साथ क्या हुआ और यह क्यों काम करता है?

आपके कोड में क्या हो रहा है, आपके पास एक कॉलम मेजर-मैट्रिक्स हाँ है, लेकिन आप अनुवाद घटकों को गलत स्थान पर रखते हैं। जब आप मैट्रिक्स को स्थानांतरित करते हैं, तो प्रविष्टि # 4 प्रविष्टि # 13, प्रविष्टि # 8 से # 13, और प्रविष्टि # 12 से # 15 तक जाती है। आखिर तुमने इसे हासिल कर ही लिया है।


0

सीधे शब्दों में कहें, तो अंतर का कारण यह है कि मैट्रिक्स गुणा कम्यूटेटिव नहीं है । संख्याओं के नियमित गुणन के साथ, यदि A * B = C तो यह निम्न प्रकार से B * A भी = C. होता है। यह मैट्रिक्स के मामले में नहीं है। इसीलिए पंक्ति-प्रमुख या स्तंभ-प्रमुख मामलों में से किसी एक को चुनना।

यह क्यों मायने नहीं रखता है, एक आधुनिक एपीआई में (और मैं विशेष रूप से यहां बात कर रहा हूं), आप अपने स्वयं के सम्मेलन का चयन कर सकते हैं और अपने मैट्रिक्स को अपने स्वयं के shader कोड में उस सम्मेलन के लिए सही क्रम में गुणा कर सकते हैं। एपीआई अब आप पर एक या दूसरे को लागू नहीं करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.