मैं एक फ्रुम के अंदर फिट होने वाले सबसे बड़े गोले को कैसे खोज सकता हूं?


12

आपको सबसे बड़ा क्षेत्र कैसा लगता है जिसे आप परिप्रेक्ष्य में बना सकते हैं?

ऊपर से देखा, यह यह होगा:

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

जोड़ा गया: दाईं ओर के फ्रॉस्ट पर, मैंने चार बिंदुओं को चिह्नित किया है जो मुझे लगता है कि हम कुछ के बारे में जानते हैं। हम फ्रुसम के सभी आठ कोनों को अप्रमाणित कर सकते हैं, और निकट और दूर के केंद्रों को समाप्त कर सकते हैं। इसलिए हम बिंदु 1, 3 और 4 को जानते हैं। हम यह भी जानते हैं कि बिंदु 2 3 से 4 के समान दूरी है। 4 से है। तो फिर हम लाइन 1 से 4 पर निकटतम बिंदु की गणना कर सकते हैं ताकि अंक 2 प्राप्त हो सके। केंद्र? लेकिन वास्तविक गणित और कोड मुझे बचता है।

मैं उन मॉडलों को आकर्षित करना चाहता हूं (जो लगभग गोलाकार हैं और जिनके पास जितना संभव हो उतना छोटा है)

अद्यतन: मैंने बॉब -ोबो और नाथन रीड द्वारा सुझाए गए इनक्रीज -ऑन-टू-प्लेन दृष्टिकोण को लागू करने की कोशिश की है :

function getFrustumsInsphere(viewport,invMvpMatrix) {
    var midX = viewport[0]+viewport[2]/2,
        midY = viewport[1]+viewport[3]/2,
        centre = unproject(midX,midY,null,null,viewport,invMvpMatrix),
        incircle = function(a,b) {
            var c = ray_ray_closest_point_3(a,b);
            a = a[1]; // far clip plane
            b = b[1]; // far clip plane
            c = c[1]; // camera
            var A = vec3_length(vec3_sub(b,c)),
                B = vec3_length(vec3_sub(a,c)),
                C = vec3_length(vec3_sub(a,b)),
                P = 1/(A+B+C),
                x = ((A*a[0])+(B*a[1])+(C*a[2]))*P,
                y = ((A*b[0])+(B*b[1])+(C*b[2]))*P,
                z = ((A*c[0])+(B*c[1])+(C*c[2]))*P;
            c = [x,y,z]; // now the centre of the incircle
            c.push(vec3_length(vec3_sub(centre[1],c))); // add its radius
            return c;
        },
        left = unproject(viewport[0],midY,null,null,viewport,invMvpMatrix),
        right = unproject(viewport[2],midY,null,null,viewport,invMvpMatrix),
        horiz = incircle(left,right),
        top = unproject(midX,viewport[1],null,null,viewport,invMvpMatrix),
        bottom = unproject(midX,viewport[3],null,null,viewport,invMvpMatrix),
        vert = incircle(top,bottom);
    return horiz[3]<vert[3]? horiz: vert;
}

मैं मानता हूँ मैं इसे पंख लगा रहा हूँ; मैं 3 आयामों में विस्तार करके 2D कोड को अनुकूलित करने का प्रयास कर रहा हूं । यह इंफ़ेयर की सही गणना नहीं करता है; गोले का केंद्र-बिंदु हर बार कैमरे और ऊपर-बाएँ के बीच की रेखा पर लगता है, और इसका बहुत बड़ा (या बहुत करीब)। क्या मेरे कोड में कोई स्पष्ट गलतियाँ हैं? क्या दृष्टिकोण, यदि तय हो, काम करता है?


क्या गोले को पूरी तरह से दूर-तल के तल पर होना चाहिए जैसा कि छवि में है?
मिकेल होजस्ट्रम

@ MikaelHögström मुझे लगता है कि वे संभव के रूप में बड़ा होने के लिए होगा?
विल

हम्म मुझे लगता है कि यह आपके उद्देश्य पर निर्भर करता है ... यदि आप दूर के विमान से एक आधे के साथ एक गोले को खींचते हैं तो यह बड़ा होगा लेकिन शायद यह आपके उद्देश्य के खिलाफ जाता है?
मिकेल होगस्ट्रॉम्

@ MikaelHögström अहा मैं आपका प्रश्न समझता हूं; हां मैं चाहता हूं कि पूरा मॉडल तैयार हो, कोई भी प्लेन इससे न टकराए।
विल

जवाबों:


12

मुझे लगता है कि आपके हताशा सममित है, क्योंकि आपका ड्राइंग ऐसा लगता है। तीन अड़चनें हैं (दो अगर आपका फ्रुम 2D है):

A. गोला पास और दूर के विमानों के बीच की दूरी से बड़ा नहीं हो सकता

यदि Dदूर की दूरी है, तो पहली बाधा बस है:

R  D / 2

B. गोलाकार पक्ष विमानों की तुलना में व्यापक नहीं हो सकता है

अब अन्य अड़चन के लिए, मान लीजिए कि αफ्रुम का आधा कोण है और Lसुदूर तल की आधी चौड़ाई है, जैसा कि इस ड्राइंग में दिखाया गया है:

छिन्नक

पहला सूत्र त्रिकोण में त्रिकोणमिति द्वारा दिया गया है। दूसरा त्रिकोण के कोणों के योग से आता है। जो हमें दूसरी बाधा देता है:

R  L tan((π - 2α) / 4)

यदि आपका फ्रुम 3 डी है, तो आपके पास नए Lऔर αमूल्यों के साथ एक तीसरा अवरोध होगा ।

अंतिम परिणाम

Rआप जिस मूल्य की तलाश कर रहे हैं min, वह तीन सीमाओं का है।

पैरामीटर कैसे प्राप्त करें

यदि आप दृश्य या विश्व अंतरिक्ष में फ़्रुम को अनप्रोजेक्ट कर सकते हैं, तो आप L, D और α की गणना निम्न तरीके से कर सकते हैं, जहाँ Pपॉइंट्स समीप के प्लेन से हैं, और Qपॉइंट्स दूर प्लेन से हैं:

formula2

तीर का अर्थ है वैक्टर, "।" डॉट उत्पाद है, और || एक वेक्टर की लंबाई इंगित करता है। ऊर्ध्वाधर आयाम में एल और α प्राप्त करने के Q2साथ Q3और उसके P2साथ बदलें P3


कैसे, फ्रुम से (निकट और दूर जाने के लिए व्यूपोर्ट पॉइंट को अनप्रोजेक्ट करके गणना की जाती है), क्या आप दृश्य के क्षेत्र का निर्धारण करते हैं? और 3 डी में तीन, सही नहीं केवल दो विकल्प हैं? कोड में अपने एल्गोरिथ्म डाल करने के लिए मेरे प्रयास हमेशा मुझे बहुत बड़ा आर देना
विल

@Will मैंने सूत्रों के साथ एक दूसरा ड्राइंग जोड़ा, जो उम्मीद में मदद करेगा।
सैम होसेवर

2

2 डी में: फ्रुम को त्रिकोण (2D) के रूप में समझें

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

इसके बाद आप खोजना चाहते हैं अन्तःवृत्त त्रिकोण की।

3 डी समस्या के रूप में, आपको एक वर्ग आधारित पिरामिड के इंफ़ेयर को खोजने की आवश्यकता है ।

अगर मेरे पास फॉर्मूला होता तो मैं उसे यहां प्रिंट कर देता, लेकिन अफसोस, मुझे फॉर्मूला नहीं पता।


2
यह शायद 2 डी में वर्टिकल या हॉरिजोन्टल फ्रुम के आवेग को खोजने के लिए पर्याप्त है, जिसके पास कम एफओवी है, कम से कम "मानक" फ्रस्टा (कतरनी या कुछ भी नहीं) के लिए।
नाथन रीड

1

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

एक क्षेत्र को केंद्र बिंदु और एक त्रिज्या द्वारा परिभाषित किया जा सकता है। Cx और Cy, समतल के केंद्र के समान है।

Cz और त्रिज्या को ऊपर सूचीबद्ध मान्यताओं के आधार पर एक समीकरण प्रणाली को हल करके प्राप्त किया जा सकता है।

T, T1, t2 और t3 के साथ या तो नीचे / टॉप प्लेन या लेफ्ट / राइट प्लेन (ऊपर देखें) में से एक है, जो सामान्य वेक्टर और t4 के मूल से दूरी के रूप में है। f दूर का केंद्र है।

t1 * cx + t2 * cy + t3 * cz - t4 = r

-fz + cz = r

t1 * cx + t2 * cy + t3 * cz - t4 = -fz + cz

t1 * cx + t2 * cy + fz - t2 = + cz - t3 * cz

t1 * cx + t2 * cy - fz - t2 = cz * (1 - t3)

cz = (t1 * cx + t2 * cy - fz - t2) / (1 - t3)

r को तब cz इस में डाला जाता है: -fz + cz = r

आप प्रोजेक्शन मैट्रिक्स youre से सभी विमानों का उपयोग कर प्राप्त कर सकते हैं। (इस मामले में ViewProjection नहीं)

बाद में आपको गोले को सही स्थान पर ले जाना होगा: C '= व्युत्क्रम (देखें) * C


1

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

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

एकमात्र दोष यह है कि सर्कल या क्षेत्र आवश्यक रूप से सबसे बड़ा नहीं होगा या संभव नहीं है। बहुत अधिक मात्रा और एक बहुत छोटे किनारे के साथ एक फ्रुम के लिए, सर्कल / गोले फ्रॉसम स्थान की तुलना में बहुत कम साझा करेंगे।

एक अन्य विचार

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

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