दुनिया भर में अक्षों को जोड़ने वाली वस्तु को कैसे घुमाना है?


15

मेरे पास एक वेक्टर 3 है जिसमें प्रत्येक अक्ष के लिए एक यूलर कोण है।

आमतौर पर, जब मैं एक रोटेशन मैट्रिक्स बनाना चाहता हूं, तो मैं अपने रोटेशन वेक्टर से संबंधित कोण से ऊपर गुजरने वाले डी 3 डीएक्समैट्रिक्सरिओटेशन एक्स जैसे कार्यों का उपयोग करूंगा और समग्र रोटेशन मैट्रिक्स बनाने के लिए मेट्रिसेस (जेडएक्सवाई) को गुणा करूंगा जो कि पूर्ण ऑब्जेक्ट ट्रांसफॉर्मेशन मैट्रिक्स बनाने के लिए उपयोग किया जाता है।

हालाँकि, यह विधि ऑब्जेक्ट स्पेस में घुमाव का एक सेट उत्पन्न करेगी। अर्थात्, (90, 0, 90) के सदिश को मेरी विधि में पास करने से (90, 90, 0) प्रभावी रूप से विश्व अंतरिक्ष में एक रोटेशन होगा।

क्या संबंधित विश्व अंतरिक्ष संरेखित अक्षों के चारों ओर घूमने में मेरे रोटेशन वेक्टर परिणामों के प्रत्येक घटक को हमेशा सुनिश्चित करने का एक तरीका है?

संपादित करें:

वर्तमान में जो कुछ हो रहा है, उसका यह एक एनीमेशन है - मुझे लाल नहीं बल्कि नीली कुल्हाड़ियों के चारों ओर घूमने का एक तरीका चाहिए।

यूलर एंगल्स

संपादित करें 2:

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


केवल तीन बार विभेदक कार्यों को कॉल करने और आप नहीं चाहते हैं कि वेक्टर्स के कुछ हिस्सों को फ़िल्टर करने से क्या गलत है (फ़ंक्शन को कॉल करने से पहले उन्हें 0 पर सेट करके)? अन्यथा मुझे यकीन नहीं है कि आप क्या हासिल करना चाहते हैं।
ट्रैविसग

फ़िल्टरिंग क्या? मैं 3 अलग-अलग फ़ंक्शनों को कॉल करता हूं और फिर उन्हें परिवर्तन मैट्रिक्स बनाने के लिए गुणा करता हूं। हालांकि यह एक स्थानीय रोटेशन होता है।
Syntac_

क्या आप यूलर कोण चाहते हैं, या विश्व कुल्हाड़ियों के बारे में रोटेशन करते हैं? ध्यान दें कि यूलर एंगल्स (जैसे en.wikipedia.org/wiki/Euler_angles ) की परिभाषा से , केवल अल्फा एंगल विश्व धुरी के बारे में कड़ाई से है। अन्य दो कोण झुके हुए कुल्हाड़ियों के सापेक्ष हैं जो जरूरी नहीं कि दुनिया की कुल्हाड़ियों के साथ मेल खाते हैं।
DMGregory

1
यूलर एंगल्स का उपयोग करके आप सभी तीन रोटेशन मैट्रिसेस को लागू करने से पहले गुणा कर रहे हैं। यदि एम, एन, ओ रोटेशन रोटेशन हैं, तो परिणाम ऑपरेशन एमएनओ वी है। मैंने जो प्रस्तावित किया है वह प्रत्येक मैट्रिक्स को अलग से लागू करना है: v1 = O v0, फिर v2 = N v1 और अंत में v3 = M v2। इस तरह से प्रत्येक vi दुनिया के निर्देशांक में होगा और आपको विश्व निर्देशांक में वर्तमान धुरी के लिए बस एक रोटेशन मैट्रिक्स का उपयोग करने की आवश्यकता है।
dsilva.vinicius

3
@ dsilva.vinicius आपके अलग किए गए रूपांतरण बिलकुल एक समान हैं, या इसे दूसरे तरीके से रखना है: MNO v == M * (N * (O v))
GuyRT

जवाबों:


1

आप टिप्पणियों के आधार पर, ऐसा लगता है कि आप ऑब्जेक्ट के ओरिएंटेशन को यूलर एंगल्स के सेट के रूप में स्टोर कर रहे हैं , और जब खिलाड़ी ऑब्जेक्ट को घुमाता है तो एंगल्स को घटाता / बढ़ाता है। अर्थात्, आपके पास इस छद्मकोड जैसा कुछ है:

// in player input handling:
if (axis == AXIS_X) object.angleX += dir;
else if (axis == AXIS_Y) object.angleY += dir;
else if (axis == AXIS_Z) object.angleZ += dir;

// in physics update and/or draw code:
matrix = eulerAnglesToMatrix(object.angleX, object.angleY, object.angleZ);

जैसा कि चार्ल्स बीट्टी नोट करते हैं , क्योंकि घुमाव की शुरुआत नहीं होती है, यह तब तक अपेक्षित नहीं होगा जब तक कि खिलाड़ी उसी क्रम में ऑब्जेक्ट को घुमाता नहीं है जिसमें eulerAnglesToMatrix()घुमाव लागू होते हैं।

विशेष रूप से, रोटेशन के निम्नलिखित अनुक्रम पर विचार करें:

  1. एक्स अक्ष के चारों ओर एक्स डिग्री द्वारा ऑब्जेक्ट घुमाएं ;
  2. Y अक्ष के चारों ओर y डिग्री से घूमने वाली वस्तु ;
  3. ऑब्जेक्ट को घुमाएगी - एक्स अक्ष के चारों ओर एक्स डिग्री;
  4. ऑब्जेक्ट को घुमाएं - Y अक्ष के चारों ओर y डिग्री।

भोले Euler कोण प्रतिनिधित्व में, जैसा कि ऊपर छद्मकोड में लागू किया गया है, ये घुमाव बाहर रद्द हो जाएंगे और वस्तु अपने मूल अभिविन्यास पर वापस आ जाएगी। वास्तविक दुनिया में, ऐसा नहीं होता है - यदि आप मुझ पर विश्वास नहीं करते हैं, तो छह-पक्षीय मरो या एक रूबिक के घन को पकड़ो, x = y = 90 ° होने दें, और इसे स्वयं आज़माएं!

समाधान, जैसा कि आप अपने स्वयं के उत्तर में नोट करते हैं , ऑब्जेक्ट के ओरिएंटेशन को रोटेशन मैट्रिक्स (या एक क्वाटर्नियन) के रूप में संग्रहीत करना है , और उपयोगकर्ता इनपुट के आधार पर उस मैट्रिक्स को अपडेट करना है। ऊपर छद्म कोड के बजाय, आप ऐसा कुछ करेंगे:

// in player input handling:
if (axis == AXIS_X) object.orientation *= eulerAnglesToMatrix(dir, 0, 0);
else if (axis == AXIS_Y) object.orientation *= eulerAnglesToMatrix(0, dir, 0);
else if (axis == AXIS_Z) object.orientation *= eulerAnglesToMatrix(0, 0, dir);

// in physics update and/or draw code:
matrix = object.orientation;  // already in matrix form!

(तकनीकी तौर पर, के बाद से किसी भी रोटेशन मैट्रिक्स या चार का समुदाय यूलर कोण का एक सेट के रूप में प्रतिनिधित्व किया जा सकता है, यह है संभव वस्तु के उन्मुखीकरण स्टोर करने के लिए उन्हें इस्तेमाल करने के लिए। लेकिन दो अनुक्रमिक रोटेशन के संयोजन के लिए शारीरिक रूप से सही नियम, प्रत्येक में प्रतिनिधित्व के रूप में यूलर कोण, एक ही रोटेशन में बल्कि जटिल है, और अनिवार्य रूप से बारी बारी से matrices / quaternions में घूर्णन, उन्हें गुणा, और फिर परिणाम को यूलर कोण में परिवर्तित करना।)


हाँ आप सही हैं यह समाधान था। मुझे लगता है कि यह कॉन्सेप्ट 3 डी के जवाब से थोड़ा बेहतर है क्योंकि वह यह आभास देता है कि क्वाटर्शन की जरूरत है लेकिन यह सच नहीं है। जब तक मैंने वर्तमान घुमाव को एक मैट्रिक्स के रूप में संग्रहीत किया और तीन यूलर कोण नहीं थे तब तक यह ठीक था।
सिन्टेक_

15

घुमाव के साथ समस्या यह है कि, ज्यादातर लोग इसे यूलर कोण के संदर्भ में सोचते हैं, क्योंकि वे समझना आसान है।

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

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

यह किसी भी 3 क्रमिक घुमावों के साथ भी होता है जब कि क्वाटर्न्स का उपयोग किया जाता है।

यहाँ छवि विवरण दर्ज करें

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

समाधान?

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

मेरा रोटेशन मैट्रिक्स एक्स और वाई और जेड के आसपास रोटेशन के परिणाम का प्रतिनिधित्व करता है।

के बजाय यूलर व्याख्या की

मेरा रोटेशन मैट्रिक्स एक्स के चारों ओर रोटेशन का प्रतिनिधित्व करता है फिर वाई फिर जेड।

यह स्पष्ट करने के लिए मैं विकिपीडिया यूलर के रोटेशन प्रमेय से उद्धरण दूंगा:

यूलर के रोटेशन प्रमेय के अनुसार, एक निश्चित बिंदु के बारे में कठोर शरीर या समन्वय प्रणाली के घूर्णन का कोई भी घुमाव या अनुक्रम किसी दिए गए कोण point के द्वारा एक रोटेशन के बराबर होता है fixed एक निश्चित अक्ष (जिसे यूलर अक्ष कहा जाता है) के बारे में। यूलर अक्ष को आमतौर पर एक यूनिट वेक्टर यू → द्वारा दर्शाया जाता है। इसलिए, तीन आयामों में किसी भी रोटेशन को एक वेक्टर यू → और एक स्केलर rotation के संयोजन के रूप में दर्शाया जा सकता है। चतुर्भुज इस अक्ष-कोण प्रतिनिधित्व को चार संख्याओं में एन्कोड करने के लिए एक सरल तरीका देते हैं, और आर 3 में मूल बिंदु के सापेक्ष एक बिंदु वेक्टर के लिए इसी रोटेशन को लागू करने के लिए।

ध्यान दें कि 3 मैट्रिक्स गुणा करना हमेशा 3 अनुक्रमिक घुमावों का प्रतिनिधित्व करेगा ।

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

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


जवाब के रूप में चिह्नित यह व्यावहारिक लगता है।
Syntac_

मुझे कुछ परेशानी हो रही है कि आप इस उत्तर के साथ क्या कहना चाह रहे हैं। क्या यह बस "यूलर एंगल्स के रूप में किसी ऑब्जेक्ट के ओरिएंटेशन को स्टोर नहीं करता है"? और यदि ऐसा है, तो बस ऐसा क्यों नहीं कहा जाता है?
इल्मरी करोनें

@IlmariKaronen यह अधिक स्पष्ट रूप से कहा जा सकता है, लेकिन मुझे लगता है कि concept3d अक्ष-कोण प्रतिनिधित्व को बढ़ावा दे रहा है; अक्ष-कोण और quaternions के बीच संबंध के लिए इस दस्तावेज़ का खंड 1.2.2 देखें । धुरी-कोण प्रतिनिधित्व उपरोक्त कारणों से लागू करना आसान है, यह जिम्बल-लॉक से ग्रस्त नहीं है, और (मेरे लिए कम से कम) यह केवल यूलर कोण के रूप में समझना आसान है।
NauticalMile

@ concept3d, यह बहुत दिलचस्प है, और मुझे वास्तव में आपका जवाब पसंद है। मेरे लिए एक बात याद आ रही है, हालांकि, लोग कीबोर्ड और माउस का उपयोग करके कंप्यूटर के साथ बातचीत करते हैं, अगर हम माउस के बारे में सोचते हैं तो हम x और y माउस डेल्टा के बारे में बात कर रहे हैं। इन एक्स, वाई डेल्टास का प्रतिनिधित्व कैसे करें एक एकल चतुर्भुज के साथ जो हम रोटेशन मैट्रिक्स उत्पन्न करने के लिए उपयोग कर सकते हैं, उदाहरण के लिए ऑब्जेक्ट ओरिएंटेशन को बदलने के लिए?
गमग्नो

@gmagno दृष्टिकोण आमतौर पर वस्तुओं या दृश्य पर माउस आंदोलन को प्रोजेक्ट करने और उस स्थान में डेल्टास की गणना करने के लिए होता है, आप एक किरण की कास्टिंग करके और चौराहे की गणना करते हैं। रे कास्टिंग, प्रोजेक्ट और अनप्रोजेक्ट के लिए खोज करें, मैं विवरणों पर किसी न किसी तरह हूं क्योंकि मैंने सीजी में अब वर्षों तक काम नहीं किया। उम्मीद है की वो मदद करदे।
concept3d

2

ऑब्जेक्ट स्पेस से विश्व स्थान पर घुमावों के संयोजन को बदलना तुच्छ है: आपको बस उस क्रम को उलट देना होगा जिसमें घुमाव लागू होते हैं।

आपके मामले में, मैट्रिक्स को गुणा करने के बजाय Z × X × Y, आपको बस गणना करने की आवश्यकता हैY × X × Z

इसके लिए एक तर्क को आंतरिक और बाहरी रोटेशन के बीच रूपांतरण पर पाया जा सकता है ।


यदि यह सत्य था, तो आपके स्रोत से निम्न कथन सत्य नहीं होगा, क्योंकि घुमाव अलग-अलग होंगे: "कोई भी बाहरी रोटेशन समान कोणों से आंतरिक रोटेशन के बराबर है, लेकिन मौलिक घुमाव के उल्टे क्रम के साथ, और इसके विपरीत । "
Syntac_

1
मुझे यहां कोई विरोधाभास नहीं दिखता। मेरा उत्तर और वह कथन दोनों सत्य हैं। और हाँ, ऑब्जेक्ट स्पेस में और दुनिया स्पेस में घूमने से अलग-अलग घुमाव मिलते हैं; यह ठीक बात है, है ना?
sam hocevar

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

1
आप गलत बोल रहे हैं। आदेश बदलने से एक ही रोटेशन नहीं होता है। आदेश को बदलने और आंतरिक रोटेशन से बाहरी घूमने के लिए स्विच करने से एक ही रोटेशन होता है।
सैम होसेवर

1
मुझे नहीं लगता कि मैं आपके प्रश्न को समझता हूं। आपका GIF लगभग 50 डिग्री के आसपास Z(ऑब्जेक्ट स्पेस), फिर 50 डिग्री के आसपास X(ऑब्जेक्ट स्पेस), फिर 45 डिग्री के आसपास Y(ऑब्जेक्ट स्पेस) का रोटेशन दिखाता है । यह ठीक वैसा ही है जैसा कि 45 डिग्री के आसपास Y( विश्व अंतरिक्ष ), फिर 50 डिग्री के आसपास X( वर्ल्ड स्पेस ), फिर 50 डिग्री के आसपास Z( वर्ल्ड स्पेस )।
सैम होसेवर

1

मैं एक उत्तर के रूप में अपना समाधान प्रदान करूंगा जब तक कोई यह नहीं बता सकता कि यह क्यों काम करता है।

हर रेंडर मैं अपने रोटेशन वेक्टर में संग्रहीत कोणों का उपयोग करके अपने चतुर्भुज का पुनर्निर्माण कर रहा था और फिर अपने अंतिम परिवर्तन के लिए चतुर्भुज को लागू कर रहा था।

हालाँकि दुनिया भर की कुल्हाड़ियों के चारों ओर रखने के लिए मुझे सभी तख्ते के पार चतुष्कोण को बनाए रखना था और केवल कोण में अंतर का उपयोग करके वस्तुओं को घुमाना था, अर्थात।

// To rotate an angle around X - note this is an additional rotation.
// If currently rotated 90, apply this function with angle of 90, total rotation = 180.
D3DXQUATERNION q;
D3DXQuaternionRotation(&q, D3DXVECTOR3(1.0f, 0.0f, 0.0f), fAngle);
m_qRotation *= q; 

//...

// When rendering rebuild world matrix
D3DXMATRIX mTemp;
D3DXMatrixIdentity(&m_mWorld);

// Scale
D3DXMatrixScaling(&mTemp, m_vScale.x, m_vScale.y, m_vScale.z);
m_mWorld *= mTemp;

// Rotate
D3DXMatrixRotationQuaternion(&mTemp, m_qRotation);
m_mWorld *= mTemp;

// Translation
D3DXMatrixTranslation(&mTemp, m_vPosition.x, m_vPosition.y, m_vPosition.z);
m_mWorld *= mTemp;

(पठनीयता के लिए क्रिया)

मुझे लगता है कि dsilva.vinicius इस बिंदु पर पहुंचने की कोशिश कर रहा था।


1

आपको रोटेशन के क्रम को संग्रहीत करने की आवश्यकता होगी।

Rotating around x 90 then rotate around z 90 !=
Rotating around z 90 then rotate around x 90.

जैसे ही वे आते हैं, अपने वर्तमान रोटेशन मैट्रिक्स और प्रत्येक रोटेशन को मुख्य रूप से स्टोर करें।


0

@ कॉन्सेप्ट 3 डी उत्तर के अलावा, आप विश्व निर्देशांक में अक्ष के चारों ओर घूमने के लिए 3 एक्सट्रिंसिक रोटेशन मैट्रिसेस का उपयोग कर सकते हैं। विकिपीडिया से उद्धरण :

एक्सट्रिंसिक घुमाव मौलिक घुमाव हैं जो स्थिर समन्वय प्रणाली एक्सिज़ के अक्षों के बारे में होते हैं। XYZ सिस्टम घूमता है, जबकि xyz तय होता है। XYZ ओवरलैपिंग xyz से शुरू करते हुए, XZZ के लिए किसी भी लक्ष्य अभिविन्यास तक पहुंचने के लिए तीन बाहरी घूर्णन की संरचना का उपयोग किया जा सकता है। यूलर या टैट ब्रायन कोण (α, γ, it) इन मौलिक घुमावों के आयाम हैं। उदाहरण के लिए, लक्ष्य अभिविन्यास निम्नानुसार पहुँचा जा सकता है:

XYZ- प्रणाली α द्वारा z- अक्ष के बारे में घूमती है। एक्स-एक्स अब एक्स-अक्ष के संबंध में कोण α पर है।

XYZ- सिस्टम β द्वारा x- अक्ष के बारे में फिर से घूमता है। Z- अक्ष अब z- अक्ष के संबंध में कोण now पर है।

XYZ- प्रणाली-द्वारा z- अक्ष के बारे में तीसरी बार घूमती है।

रोटेशन मैट्रिसेस का उपयोग एक्सट्रिंसिक रोटेशन के अनुक्रम को दर्शाने के लिए किया जा सकता है। उदाहरण के लिए,

R = Z (=) Y (β) X (α)

यदि एक्स-ज़ीज़ के बारे में बाहरी रोटेशन की एक संरचना का प्रतिनिधित्व करता है, अगर पूर्व-स्तंभ वाले स्तंभों के लिए उपयोग किया जाता है, जबकि

R = X (α) Y (β) Z (α)

पंक्ति वैक्टर पोस्ट-गुणा करने के लिए उपयोग किए जाने पर बिल्कुल उसी संरचना का प्रतिनिधित्व करता है।

तो क्या आप की जरूरत है कि आप आंतरिक (या स्थानीय अंतरिक्ष) रोटेशन का उपयोग कर के संबंध में रोटेशन के आदेश उल्टा है। @ सिन्टैक ने एक zxy रोटेशन के लिए कहा, इसलिए हमें एक ही परिणाम प्राप्त करने के लिए एक yxz एक्सट्रिंसिक रोटेशन करना चाहिए। कोड नीचे है:

मैट्रिक्स मूल्यों की व्याख्या यहाँ है

// Init things.
D3DXMATRIX *rotationMatrixX = new D3DXMATRIX();
D3DXMATRIX *rotationMatrixY = new D3DXMATRIX();
D3DXMATRIX *rotationMatrixZ = new D3DXMATRIX();
D3DXMATRIX *resultRotationMatrix0 = new D3DXMATRIX();
D3DXMATRIX *resultRotationMatrix1 = new D3DXMATRIX();

D3DXMatrixRotationX(rotationMatrixX, angleX);
D3DXMatrixRotationY(rotationMatrixY, angleY);
D3DXMatrixRotationZ(rotationMatrixZ, angleZ);

// yx extrinsic rotation matrix
D3DXMatrixMultiply(resultRotationMatrix0, rotationMatrixY, rotationMatrixX);
// yxz extrinsic rotation matrix
D3DXMatrixMultiply(resultRotationMatrix1, resultRotationMatrix0, rotationMatrixZ);

D3DXVECTOR4* originalVector = // Original value to be transformed;
D3DXVECTOR4* transformedVector = new D3DXVECTOR4();

// Applying matrix to the vector.
D3DXVec4Transform(transformedVector, originalVector, resultRotationMatrix1);

// Don't forget to clean memory!

यह कोड डिडक्टिक है, इष्टतम नहीं है, क्योंकि आप कई डी 3 डीएक्समैट्रीक्स मैट्रीस का पुन: उपयोग कर सकते हैं।


1
सॉरी यार यह सही नहीं है। मैट्रिक्स / वेक्टर गुणा गुणात्मक है। यह संयुक्त मैट्रिक्स गुणन के समान ही है।
कॉन्सेप्ट

तुम सही हो। मैंने बाहरी और आंतरिक रोटेशन की अवधारणाओं को मिलाया है।
dsilva.vinicius

मैं इस उत्तर को ठीक करूँगा।
dsilva.vinicius

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