कैसे उत्पन्न ज्यामिति के लिए भूतल सामान्य की गणना करने के लिए


12

मेरे पास एक वर्ग है जो कॉलिंग कोड से इनपुट के आधार पर एक 3D आकार बनाता है। इनपुट लंबाई, गहराई, चाप, आदि जैसी चीजें हैं। मेरा कोड पूरी तरह से ज्यामिति उत्पन्न करता है, हालांकि सतह के मानदंडों की गणना करते समय मैं मुसीबत में चल रहा हूं। जब जलाया जाता है, तो मेरे आकार में गलत सतह मानदंड से बहुत विचित्र रंग / बनावट होती है जिनकी गणना की जा रही है। मेरे सभी शोध से मेरा मानना ​​है कि मेरा गणित सही है, ऐसा लगता है कि मेरी तकनीक या विधि में कुछ गड़बड़ है।

एक उच्च स्तर पर कैसे एक उत्पन्न आकार के लिए सतह मानदंडों की गणना करने के लिए प्रोग्रामेटिक रूप से जाना जाता है? मैं अपने कोड के लिए iOS पर Swift / SceneKit का उपयोग कर रहा हूं लेकिन एक सामान्य उत्तर ठीक है।

मेरे पास दो सरणियाँ हैं जो मेरे आकार का प्रतिनिधित्व करती हैं। एक 3 डी पॉइंट की एक सरणी है जो आकार बनाने वाले कोने का प्रतिनिधित्व करता है। अन्य सरणी पहले सरणी के अनुक्रमित की एक सूची है जो त्रिकोण में कोने को मैप करती है। मुझे उस डेटा को लेने की आवश्यकता है और एक तीसरा सरणी उत्पन्न करना है जो सतह के मानदंडों का एक सेट है जो आकार के प्रकाश में सहायता करता है। ( SCNGeometrySourceSemanticNormalसीनकीट में देखें )

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


और संदर्भ चाहिए। क्या आप एक पैरामीट्रिक सतह के लिए विश्लेषणात्मक मानदंडों की गणना करने की कोशिश कर रहे हैं? एक निहित सतह? या आप एक सामान्य त्रिकोण जाल से मानदंडों की गणना करना चाहते हैं? या कुछ और?
नाथन रीड

धन्यवाद, मैंने और विस्तार से जोड़ा। आपके प्रश्न का उत्तर देने के लिए मुझे एक सामान्य त्रिकोण जाल से मानदंडों की गणना करने की आवश्यकता है। हालांकि यह स्पष्ट होना चाहिए कि इनपुट के आधार पर मेष अलग है। मेरा आकार एक 3D तीर है, यहाँ एक उदाहरण के रूप में यह 2 अलग-अलग रूपों (यानी रेडियल और रैखिक) का स्क्रीनशॉट है। वर्ग अनुरोध के अनुसार चौड़ाई, गहराई, लंबाई, चाप और त्रिज्या की त्रिज्या को बदलता है। cl.ly/image/3O0P3X3N3d1d आप इसे हल करने में अपने खराब प्रयासों के साथ मुझे मिल रही विषम प्रकाश व्यवस्था देख सकते हैं।
मैकिंजोश

3
संक्षिप्त संस्करण यह है: प्रत्येक त्रिकोणीय की गणना करें जो इसे छूने वाले सभी त्रिकोणों के मानदंडों के सामान्यीकृत योग के रूप में सामान्य है। हालांकि, यह सब कुछ सुचारू बना देगा, जो इस आकार के लिए नहीं हो सकता है। मैं बाद में पूर्ण उत्तर देने की कोशिश करूंगा।
नाथन रीड

चिकना मैं क्या के लिए जा रहा हूँ!
मैकिंजोश

4
ज्यादातर मामलों में, यदि आप विश्लेषणात्मक रूप से शीर्ष पदों की गणना करते हैं, तो आप मानदंडों को विश्लेषणात्मक रूप से भी गणना कर सकते हैं। एक पैरामीट्रिक सतह के लिए, मानदंड दो ग्रेडिएंट वैक्टर के क्रॉस उत्पाद हैं। त्रिभुज मानदंडों के औसत की गणना करना केवल एक अनुमान है, और अक्सर इसके परिणामस्वरूप बहुत अधिक खराब गुणवत्ता होती है। मैं एक उत्तर पोस्ट करूंगा, लेकिन मैंने पहले ही SO ( stackoverflow.com/questions/27233820/… ) पर एक विस्तृत उदाहरण पोस्ट कर दिया था, और मुझे यकीन नहीं है कि हम यहां पर प्रतिकृति सामग्री चाहते हैं।
रेटो कोराडी

जवाबों:


10

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

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

छवि हम बाद में हैं

चित्र 1 : आप जो परिणाम चाहते हैं।

वास्तव में आप केवल घुमावदार क्षेत्र के कोने को औसत करना चाहते हैं, अन्य सभी वे सामान्य उपयोग कर सकते हैं जो उन्हें अकेले अपने त्रिकोण के रूप में मिलते हैं। तो आप 9 अलग-अलग क्षेत्रों के रूप में मेष के बारे में सोच रहे हैं जो दूसरों के बिना नियंत्रित किए जाते हैं।

जाल और मानदंड दिखाना]

छवि 2 : छवि मेष संरचना और मानदंड दिखा रही है।

आप निश्चित रूप से प्राथमिक मानदंडों से सामान्य कोण से बाहर के मानदंडों को शामिल नहीं करके स्वचालित रूप से इसे घटा सकते हैं। स्यूडोकोड:

For vertex in faceVertex:
    normal = vertex.normal
    For adjVertex in adjacentVertices:
        if anglebetween(vertex.normal, adjVertex.normal )  < treshold:
            normal += adjVertex.normal
    normal = normalize(normal)

यह काम करता है, लेकिन आप सृजन के समय इस सब से बच सकते हैं क्योंकि आप समझते हैं कि अलग-अलग विमान अलग-अलग तरीके से काम कर रहे हैं। तो केवल घुमावदार पक्षों को सामान्य दिशा विलय की आवश्यकता होती है। और वास्तव में आप सीधे उन्हें अंतर्निहित गणितीय आकार से शांत कर सकते हैं।


10

मैं मुख्य रूप से उत्पन्न आकार के लिए कंप्यूटिंग मानदंडों के तीन तरीके देखता हूं।

विश्लेषणात्मक मानदंड

कुछ मामलों में आपके पास मानदंडों को उत्पन्न करने के लिए सतह के बारे में पर्याप्त जानकारी है। उदाहरण के लिए, एक क्षेत्र पर किसी भी बिंदु का सामान्य गणना करने के लिए तुच्छ है। सीधे शब्दों में कहें, जब आप फ़ंक्शन के व्युत्पन्न को जानते हैं, तो आप सामान्य भी जानते हैं।

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

वर्टेक्स मानदंड

दो वैक्टरों का क्रॉस उत्पाद वे जिस विमान से संबंधित होता है, उसे एक सीधा लंबवत देता है। तो एक त्रिभुज का सामान्य होना सीधा है:

vec3 computeNormal(vec3 a, vec3 b, vec3 c)
{
    return normalize(crossProduct(b - a, c - a));
}

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

vec3 computeNormal(vertex a)
{
    vec3 sum = vec3(0, 0, 0);
    list<vertex> adjacentVertices = getAdjacentVertices(a);
    for (int i = 1; i < adjacentVertices; ++i)
    {
        vec3 b = adjacentVertices[i - 1];
        vec3 c = adjacentVertices[i];
        sum += crossProduct(b - a, c - a);
    }
    if (norm(sum) == 0)
    {
        // Degenerate case
        return sum;
    }
    return normalize(sum);
}

यदि आप क्वाड्स के साथ काम कर रहे हैं, तो एक अच्छी चाल है जिसका आप उपयोग कर सकते हैं: एक क्वाड एब्सकांड के लिए , उपयोग करें crossProduct(c - a, d - b)और यह अच्छी तरह से उन मामलों को हैंडल करेगा जहां क्वाड वास्तव में एक त्रिकोण है।

Iñigo quilez ने इस विषय पर कुछ छोटे लेख लिखे: एक मेष का चतुर सामान्यीकरण , और सामान्य पक्षीय बहुभुज का क्षेत्रफल

आंशिक व्युत्पन्न से सामान्य

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


1
एक चौथा तरीका है, कलाकार आपूर्ति किए गए
मानदंड

@ जूजा: मेरा मानना ​​है कि आप सामान्य नक्शे की बात कर रहे हैं? मैंने कभी भी मैन्युअल रूप से अधिकृत मानदंडों के बारे में नहीं सुना है।
जुलिएन गुर्टॉल्ट

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

1
इन्हें कभी-कभी "स्पष्ट मानदंड" (3ds अधिकतम और माया शब्दावली) के रूप में संदर्भित किया जाता है।
दुसान बोसनजक 'पैलहेड'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.