सवाल एंड्रॉइड: मैट्रिक्स -> प्रीकोनकैट और पोस्टकोनैट के बीच क्या अंतर है?


मैं उपयोग कर रहा हूँ मैट्रिक्स बिटमैप्स को स्केल और घुमाने के लिए। अब मैं सोच रहा हूं कि प्रीकोनकैट और पोस्टकोनैट के बीच क्या अंतर है, या अधिक सटीक रूप से अंतर:

जो मैं अब तक पता लगा सकता हूं उससे सेटरोट हमेशा पूरे मैट्रिक्स को ओवरराइट करता है, जबकि प्रीरोटेट और पोस्टरोटेट के साथ मैं मैट्रिक्स में कई बदलाव लागू कर सकता हूं (जैसे स्केलिंग + रोटेशन)। हालांकि, पोस्टरोटेट या प्रीरोटेट का उपयोग करने से मैंने उन मामलों के लिए कोई अलग परिणाम नहीं दिया है जिनका मैंने उपयोग किया था।


44
2017-10-04 13:18


मूल




जवाब:


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

कंप्यूटर ग्राफिक्स में, हम वैक्टर के रूप में पिक्सल (या 3 डी, शिखर) में प्रतिनिधित्व कर सकते हैं। यदि आपकी स्क्रीन 640x480 है, तो आपकी स्क्रीन के बीच में बिंदु के लिए 2 डी वेक्टर है (मेरे शर्मीली मार्कअप को क्षमा करें):

[320]
[240]
[  1]

मैं समझाऊंगा कि क्यों बाद में 1 महत्वपूर्ण है। परिवर्तनों का उपयोग अक्सर प्रतिनिधित्व किया जाता है मैट्रिक्स क्योंकि यह उल्लेख किया गया है कि यह एक साथ श्रृंखला के साथ बहुत सरल (और बहुत ही कुशल) है। 1.5 के कारक से ऊपर बिंदु को स्केल करने के लिए, आप कर सकते हैं बाएं गुणा निम्नलिखित मैट्रिक्स द्वारा:

[1.5   0   0]
[  0 1.5   0]
[  0   0   1]

आपको यह नया बिंदु मिलेगा:

[480]
[360]
[  1]

जो आपकी स्क्रीन के कोने से संबंधित 1.5 द्वारा स्केल किए गए मूल बिंदु का प्रतिनिधित्व करता है (0, 0)। यह महत्वपूर्ण है: मूल के संबंध में स्केलिंग हमेशा किया जाता है। यदि आप अपने केंद्र (जैसे स्प्राइट के बीच) के रूप में किसी अन्य बिंदु के साथ स्केल करना चाहते हैं, तो आपको मूल में और उससे अनुवादों में पैमाने को "लपेटना" चाहिए। उत्पत्ति के लिए हमारे मूल बिंदु का अनुवाद करने के लिए मैट्रिक्स यहां दिया गया है:

[1  0  -320]
[0  1  -240]
[0  0     1]

कौन सी पैदावार:

[320*1 + 1*-320]   [0]
[240*1 + 1*-240] = [0]
[     1*1      ]   [1]

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

अब, मैट्रिक्स गुणा आम तौर पर कम्यूटिव नहीं है, इसलिए जब एक रूपांतरण "जोड़ना" (द्वारा गुणा आपका मैट्रिक्स) आपको यह निर्दिष्ट करने की आवश्यकता है कि आप बाएं-गुणा या दाएं-गुणा कर रहे हैं या नहीं। यह अंतर यह है कि आपके परिवर्तनों को किस क्रम में जंजीर किया गया है। अपने मैट्रिक्स को सही-गुणा करके (उपयोग करें preRotate()) आप संकेत दे रहे हैं कि रोटेशन चरण होना चाहिए से पहले अन्य सभी परिवर्तन जिन्हें आपने अभी पूछा है। यह हो सकता है कि आप क्या चाहते हैं, लेकिन यह आमतौर पर नहीं है।

अक्सर, इससे कोई फर्क नहीं पड़ता। यदि आपके पास केवल एक परिवर्तन है, उदाहरण के लिए, यह कभी मायने रखता नहीं है :) कभी-कभी, आपके परिवर्तन एक ही प्रभाव के साथ किसी भी क्रम में हो सकते हैं, जैसे स्केलिंग और रोटेशन - मेरा रैखिक बीजगणित जंगली है, लेकिन मेरा मानना ​​है कि इस मामले में मैट्रिक्स गुणा वास्तव में कम्यूटिव है क्योंकि स्केल मैट्रिक्स है सममित, यानी, यह विकर्ण में खुद को दर्पण करता है। लेकिन वास्तव में, बस इसके बारे में सोचें: अगर मैं कुछ तस्वीरों को 10 डिग्री घड़ी की दिशा में घुमाता हूं और फिर इसे 200% तक स्केल करता है, तो ऐसा लगता है जैसे मैंने इसे पहले स्केल किया, फिर इसे घुमाया।

यदि आप कुछ वीडर कंपाउंड ट्रांसफॉर्मेशन कर रहे थे, तो आप एक विसंगति नोटिस करना शुरू कर देंगे। मेरी सलाह है कि साथ रहना है postRotate()


123
2018-02-25 23:15



दस्तावेज़ों के अनुसार, एम। रेपोनकैट (अन्य)> एम '= एम * अन्य, एम.पोस्टकोनकैट (अन्य)> एम' = अन्य * एम, मैं वर्तमान में इनमें से कुछ को आजमा रहा हूं लेकिन ऐसा लगता है कि 'प्री' सेट करता है आपके द्वारा पहले से किए गए कार्यों के बाद नया ऑपरेशन, और 'पोस्ट' इससे पहले करता है। मैं अनुवाद करने के बाद स्केलिंग कर रहा हूं, इसे स्केल करने की आवश्यकता है और फिर अनुवाद करना है क्योंकि अनुवाद स्केल किए गए निर्देशांक में है। यह काम करता है अगर मैं 'पूर्व' लेकिन अगर मैं 'पोस्ट' नहीं करता हूं। यह संकेत मुझे भ्रमित कर रहा है, इसलिए अगर मैं गलत हूं तो मुझे बताएं। - Kratz
मुझे दस्तावेज़ों को भी दोगुना करना और ट्रिपल करना था। नामकरण योजना बल्कि उलझन में है, इसलिए मैं इसे पीछे से प्राप्त कर सकता हूं। मुझे यकीन नहीं कि मैं समझा हूँ तुंहारे नोटेशन, हालांकि :) other*M एक बाएं गुणा है, और उपज चाहिए Mइसके बाद के परिवर्तन otherके। मुझे लगता है। - Cheezmeister
मुझे यह नोटेशन मिला है: developer.android.com/reference/android/graphics/... मुझे नामकरण का नाम भी मिल रहा है। - Kratz
संक्षेप में और गहराई से स्पष्टीकरण प्यार! +1। - rupps
@ चेज़ीमेस्टर क्या आप कुछ स्रोत सुझा सकते हैं जहां मैं कंप्यूटर ग्राफिक्स पर और अधिक जानकारी प्राप्त कर सकता हूं, जो आपके उत्तर की तरह गहराई से समझाया गया है - DeltaCap


मैंने कल सवाल का जवाब दिया, लेकिन मुझे आज कुछ समय गलत लगता है, इसलिए मैं यहां जवाब सही करता हूं:

matrix:  float[] values ={1.2f,0.5f,30,0.5f,1.2f,30,0,0,1};

//as we all know, the basic value in matrix,means no transformation added
matrix2:  float[] values2 ={1f,0,0,0,1f,0,0,0,1};

Let's say our matrix values are the values above.

1, जब हम नीचे की तरह परिवर्तन करते हैं:

matrix.preTranslate(-50, -50);

is equals to do sequence transformation to matrix2 above like below:

matrix2.postTranslate(-50, -50);
matrix2.postSkew(0.5f/1.2f,0.5f/1.2f);// note here
matrix2.postScale(1.2f, 1.2f);
matrix2.postTranslate(30, 30);

2, जब हम नीचे की तरह परिवर्तन करते हैं:

matrix.preRotate(50);

is equals to do sequence transformation to matrix2 like below:

matrix2.postRotate(50);
matrix2.postSkew(0.5f/1.2f,0.5f/1.2f);
matrix2.postScale(1.2f, 1.2f);
matrix2.postTranslate(30, 30);

3, जब हम नीचे की तरह परिवर्तन करते हैं:

matrix.preScale(1.3f,1.3f);

is equals to do sequence transformation to matrix2 like below:

matrix2.postScale(1.3f,1.3f);
matrix2.postSkew(0.5f/1.2f,0.5f/1.2f);
matrix2.postScale(1.2f, 1.2f);
matrix2.postTranslate(30, 30);

4, जब हम नीचे की तरह परिवर्तन करते हैं:

 matrix.preSkew(0.4f,0.4f);

नीचे मैट्रिक्स 2 के अनुक्रम परिवर्तन करने के बराबर है:

 matrix2.postSkew(0.4f,0.4f);
 matrix2.postSkew(0.5f/1.2f,0.5f/1.2f);
 matrix2.postScale(1.2f, 1.2f);
 matrix2.postTranslate(30, 30);

4
2017-09-18 03:34