मैं लक्ष्य बिंदु के बारे में कैमरे की परिक्रमा कैसे कर सकता हूं?


18

मैं एक दृश्य खींच रहा हूं जहां कैमरा स्वतंत्र रूप से ब्रह्मांड के बारे में चलता है। कैमरा वर्ग दृश्य (या देखने ) बिंदु, कैमरे की स्थिति और अप वेक्टर पर नज़र रखता है । इन वैक्टर / बिंदुओं को तब ग्लूकोल्ट में पारित किया जाता है।

पैन और ज़ूम लागू करने के लिए लगभग तुच्छ हैं। हालाँकि, मैं एक मुद्दे के बहुत अधिक होने के बिंदु पर नज़र के बारे में रोटेशन पा रहा हूँ । मैं एक फ़ंक्शन लिखना चाहता हूं Camera.rotate जो 2 कोण लेता है, एक जो ऊपर / नीचे घूमता है और एक जो एक काल्पनिक क्षेत्र के साथ बाएं / दाएं घूमता है जो बिंदु पर नज़र के बारे में केंद्रित है ।

क्या इसे करने का कोई आसान तरीका है?

मैंने (संक्षेप में) quaternions के बारे में पढ़ा है, लेकिन मैं यह देखना चाहता था कि मेरे दृश्य के अपेक्षाकृत सरल निर्माण को देखते हुए एक आसान समाधान था या नहीं।


क्या आपके पास अपने टूलबॉक्स में कुछ भी है जो मूल के चारों ओर एक बिंदु को घुमाने के लिए है, एक अक्ष और एक कोण दिया गया है?
सैम होसेवर

Quaternions की मेरी ढीली समझ के अलावा और कुछ नहीं। जितना मैं यह देख रहा हूं, मुझे लगता है कि Quaternions का जवाब हो सकता है। हालाँकि, मैं अनिश्चित हूँ कि कैसे कुल्हाड़ी के सूत्र में उपयोग करने के लिए अक्ष x, y और z मानों की गणना की जाए ।
ल्यूक

मैं आपको नहीं बताऊंगा कि quaternions जाने का रास्ता नहीं है। वे आपकी समस्या का बहुत अच्छा समाधान हैं। लेकिन आपको जीएल और जीएलयू के साथ बातचीत करने के लिए एक चतुर्भुज वर्ग और तरीके की आवश्यकता होगी, और मुझे लगता है कि आपको पहले परिवर्तन मैट्रिसेस से परिचित होने का प्रयास करना चाहिए। दूसरे असहमत हो सकते हैं।
sam hocevar

इस बात पर विचार करें कि आप दुनिया के अंतरिक्ष में जाने के लिए या कैमरा स्पेस में जाने के लिए घूर्णन को लागू करने के लिए क्या आदेश देते हैं
चार्ली

जवाबों:


25

आप जो पूछ रहे हैं उसे आर्कबॉल रोटेशन कहा जाता है। यदि आप समझते हैं कि वे कैसे काम करते हैं, तो Quaternions आसान समाधान है। आप हालांकि quaternions के बिना ही प्राप्त कर सकते हैं।

पूर्व आवश्यक वस्तुएँ

क्या आप जानते हैं कि वस्तुओं को सामान्य रूप से कैसे घुमाना है? मान लीजिए कि आपके मूल में कोई वस्तु है। क्या आप जानते हैं कि आप इसे कैसे घुमाते हैं (संकेत: कुछ रोटेशन मैट्रिक्स से गुणा करें)? यदि हाँ, तो मैं मान रहा हूँ कि यदि आप पहले वस्तु का अनुवाद करते हैं और फिर उसे घुमाते हैं तो क्या होगा?

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

समाधान

  • कैमरे के ऊपर और सही वैक्टर प्राप्त करें। ध्यान दें कि उन्हें सामान्य किया जाना चाहिए।
  • वेक्टर को फोकस बिंदु से कैमरे तक ले जाएं (कैमपोजिशन - फोकस)। यह वेक्टर है जिसे आप घुमाने जा रहे हैं। आइए इस कैमफोकस वैक्टर को कॉल करें ।
  • तय करें कि आप कैमरे के संबंध में कितना जम्हाई / पिच में घूमना चाहते हैं
  • दो रोटेशन मेट्राइस बनाएं। 1 रोटेशन मैट्रिक्स आपके द्वारा तय किए गए अक्ष और जबड़े कोण के रूप में कैमरे के ऊपर का उपयोग करेगा । दूसरा रोटेशन मैट्रिक्स आपके द्वारा तय किए गए अक्ष और पिच कोण के रूप में कैमरे के अधिकार का उपयोग करेगा ।
  • अब नए रोटेशन मेट्रिसेस के साथ camFocusVector को घुमाएं । यह अब मूल के सापेक्ष कैमरे की आपकी नई स्थिति है। हम निश्चित रूप से, यह फोकस बिंदु के सापेक्ष होना चाहते हैं ...
  • CamFocusVector पर फोकस बिंदु स्थिति जोड़ें । यह अब आपके कैमरे की नई स्थिति है। तदनुसार अपने कैमरे का अनुवाद करें।
  • अंत में, कैमरे से अपने लुकअट () फ़ंक्शन को कॉल करके फ़ोकस पॉइंट पर ध्यान केंद्रित करने के लिए कहें

चेतावनियां

आपको कुछ मामलों या विलक्षणताओं की तलाश करनी होगी, जिस पर आपका कैमरा काम करना बंद कर देगा। उदाहरण के लिए सीधे नीचे / ऊपर देख रहे हैं। मैं आपको बताऊंगा कि इनसे कैसे निपटा जाए।

EDIT1: कैसे कैमरे के orthonormal वैक्टर पुनर्गणना करने के लिए

आप पहले से ही कैमरे की दिशा जानते हैं ((CameraPos - focusPoint) .normalize ())। अब मान लें कि आपके कैमरे का अप + वाई है (या w / e आपकी दुनिया की वर्तमान धुरी है ... जो आपके ऊपर है)। अब बस पार दिशा के साथ अप प्राप्त करने के लिए सही । किया हुआ? नहीं! आपका अप वेक्टर अब अन्य दो के लिए रूढ़िवादी नहीं है। इसे ठीक करने के लिए, दिशा के साथ दाईं ओर क्रॉस करें और आप अपना नया उठाएं

ध्यान दें कि ग्राम-श्मिट वास्तव में वैक्टर को ओर्थोनॉर्मालाइज करने के लिए क्या करना चाहिए।

फिर, यह के रूप में चेतावनियां लिख लेना चाहिए कुछ मामलों में काम करने के लिए असफल हो जायेगी ( दिशा के समानांतर है ऊपर उदाहरण के लिए)।


ध्यान दें कि सही वेक्टर का उपयोग करके प्राप्त किया जा सकता है normalize(up ^ camFocusVector)(या इसके विपरीत अगर बाएं हाथ से)।
सैम होसेवर

अब तक अच्छा लग रहा है, बाएं / दाएं रोटेशन के लिए खूबसूरती से काम किया (मेरे पास अप वेक्टर है इसलिए यह आसान है)। आपकी टिप्पणी @SamHocevar में '^' का क्या अर्थ है? क्या वह क्रॉस उत्पाद है? एक बार अनुवाद करने के बाद, मैं अप वेक्टर को कैसे पुनः स्थापित कर सकता हूं?
ल्यूक

@ ल्यूक: मेरे ईडीआईटी 1 की जांच करें
समोरसा

1
@Samaursa आपका बहुत-बहुत धन्यवाद। आपका समाधान पूरी तरह से काम करता है, और मैंने इस प्रक्रिया में बहुत कुछ सीखा है!
ल्यूक

2
यह एक उत्कृष्ट उत्तर है, आपके स्पष्टीकरण के लिए बहुत बहुत धन्यवाद। मेरे मामले में, मैं चाहता था कि कैमरा केवल XY विमान में लक्ष्य बिंदु के बारे में घुमाए, और इसलिए सभी गणनाएं करने के बाद, मैंने हमेशा CameraRight.z को 0 पर सेट किया और फिर कैमराअप वेक्टर की गणना की। इसने वांछित प्रभाव दिया। बस के आदान-प्रदान में सोचा
codemonkey

1

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

यह XNA में है, लेकिन IIRC मैंने पहले इस कार्यान्वयन का उपयोग किया है, और इसने काफी अच्छा काम किया है:

http://roy-t.nl/index.php/2010/02/21/xna-simple-arcballcamera/


यह कार्यान्वयन केवल सही वेक्टर के साथ सीधे स्थानांतरित करने के लिए प्रतीत होता है, जो राशि के छोटे मूल्यों के लिए एक आर्कबॉल को अनुमानित करेगा । वह LookAt बिंदु को भी स्थानांतरित कर रहा है, जहां मैं कैमरा स्थानांतरित करना चाहता हूं (करीब, लेकिन सूक्ष्म रूप से अलग)। मेरा मानना ​​है कि समरसता ने इसे प्राप्त करने का सबसे सरल तरीका प्रदान किया है।
ल्यूक

आपकी प्रतिक्रिया के लिए धन्यवाद। मुझे यह स्वीकार करना चाहिए कि मैंने इस कार्यान्वयन को "ब्लैकबॉक्स" के रूप में थोड़ा उपयोग किया लेकिन मुझे कोई समस्या नज़र नहीं आई। स्पष्ट करने के लिए आप शायद MoveCameraRight / MoveCameraForward तरीकों के बारे में बात कर रहे थे? उन तरीकों को कैमरे को पैन करने के लिए जोड़ा गया था, लेकिन आर्कबॉल इंटरफ़ेस का हिस्सा नहीं हैं। यदि आप लक्ष्य के चारों ओर कैमरा घुमाना चाहते हैं, तो आप बस यव या पिच गुणों को बदल सकते हैं।
डेविड गाविया

क्षमा करें, आप सही हैं, वे विधियाँ हैं। मैंने ध्यान नहीं दिया कि कैसे उन्होंने मैट्रिक्स के लिए एक गंदे झंडे को सेट किया था जब जम्हाई और पिच को बदल दिया गया था।
ल्यूक

0

यहाँ एक बिंदु के चारों ओर घूमने के लिए मेरा कोड है, अपने आप को इसे बहुत पुन: उपयोग करते हुए पाया।

float distance;      // Straight line distance between the camera and look at point

// Calculate the camera position using the distance and angles
float camX = distance * -sinf(camAngleX*(M_PI/180)) * cosf((camAngleY)*(M_PI/180));
float camY = distance * -sinf((camAngleY)*(M_PI/180));
float camZ = -distance * cosf((camAngleX)*(M_PI/180)) * cosf((camAngleY)*(M_PI/180));

// Set the camera position and lookat point
gluLookAt(camX,camY,camZ,   // Camera position
          0.0, 0.0, 0.0,    // Look at point
          0.0, 1.0, 0.0);   // Up vector

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

अब जब आपने उल्लेख किया है कि, मुझे लगता है कि समस्या को देखने के दो अलग-अलग तरीके हैं। अपने आवेदन में मैंने समुद्र पर एक लक्ष्य द्वीप के चारों ओर घूमने के लिए आर्कबेल कैमरे का उपयोग किया, और यदि मैंने स्वतंत्रता के 3 अक्षों का उपयोग किया तो यह स्पष्ट रूप से गलत दिखाई देगा (जैसे कि द्वीप को उल्टा या बग़ल में देखना)।
डेविड गुवेया

मैं यहां कैमरा कोण कैसे प्राप्त करूं?
राफस्वस

0

यह प्राप्त करने के लिए बहुत सरल एल्गोरिथ्म है कि बहुत बढ़िया है:

पी के केंद्र बिंदु के बारे में आप को घुमाना चाहते हैं ("" या "लक्ष्य" बिंदु को देखें):

translate(-P)

rotate horizontal
rotate vertical

translate(P)

मैंने इसका और इसका अच्छा उपयोग किया।

स्रोत बहन-साइट स्टैकओवरफ़्लो में पाया गया: /programming/287655/opengl-rotating-a-camera-around-a-point

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