2010-03-09 10 views
5

मैं दो पुस्तकालयों (ओपनकास्केड और डीडब्ल्यूएफ टूलकिट) के शीर्ष पर एक सीएडी फ़ाइल कनवर्टर बना रहा हूं।'त्रिभुज-सूप' से अद्वितीय शिखर खोजें

को देखते हुए:

मैं त्रिकोणीय चेहरे की एक सूची के रूप में एक जाल जेनरेट किया है एक मॉडल अपने आवेदन के माध्यम से निर्माण के लिए फार्म

हालांकि, मेरे सवाल का plattform नास्तिक है। प्रत्येक त्रिभुज को तीन चरमों के माध्यम से परिभाषित किया जाता है, जिसमें तीन फ्लोट (x, y & z समन्वय) शामिल होते हैं। चूंकि त्रिकोण एक जाल बनाते हैं, इसलिए अधिकांश कोष्ठक एक त्रिकोण से अधिक साझा किए जाते हैं।

लक्ष्य:

मैं अद्वितीय कोने की सूची प्राप्त करने के लिए, और इस सूची में तीन सूचकांकों की tuples से मिलकर चेहरे की एक सरणी उत्पन्न करने के लिए की जरूरत है।

//step 1: build a list of unique vertices 
for each triangle 
    for each vertex in triangle 
     if not vertex in listOfVertices 
     Add vertex to listOfVertices 

//step 2: build a list of faces 
for each triangle 
    for each vertex in triangle 
     Get Vertex Index From listOfvertices 
     AddToMap(vertex Index, triangle) 

जब मैं एक कार्यान्वयन जो इस, चरण 1 (अद्वितीय कोने की सूची की पीढ़ी) करता है वास्तव में हे के क्रम में धीमी है (एन:

यह क्या मैं करना चाहता हूँ है !), चूंकि प्रत्येक चरम सूची की सूची में पहले से मौजूद सभी शीर्षकों से तुलना की जाती है। मैंने सोचा "अरे, std :: मैप का उपयोग करके मेरे शिखर के घटकों के एक हैशप को बनाने दें, जो चीजों को गति देना चाहिए!", केवल यह पता लगाने के लिए कि तीन फ़्लोटिंग पॉइंट मानों से एक अनूठी कुंजी उत्पन्न करना एक छोटा काम नहीं है।

यहां, स्टैक ओवरफ्लो के विशेषज्ञ खेल में आते हैं: मुझे किसी प्रकार का हैश-फ़ंक्शन चाहिए जो 3 फ्लोट्स पर काम करता है, या कोई अन्य फ़ंक्शन 3 डी-वर्टेक्स स्थिति से अद्वितीय मूल्य उत्पन्न करता है।

+0

इस कशेरुक विशिष्टता को कितना मजबूत होना चाहिए? मेरा मतलब है, क्या आप बस अंतरिक्ष को बचाने की कोशिश कर रहे हैं, या आपको बहुत मजबूत टोपोलॉजी की आवश्यकता है। मान लीजिए वर्टेक्स वीए और वीबी अलग-अलग आईडी पीएन और पीक प्राप्त करते हैं लेकिन वास्तव में वास्तव में 'वही' हैं, क्या यह एक सौदा ब्रेकर है? – Tarydon

+0

हां, ऐसा इसलिए होगा क्योंकि मैं टोपोलॉजी के मेष निर्यात करने की कोशिश कर रहा हूं। यदि स्रोत में स्रोत से एक ही वर्टेक्स कई बार मौजूद होगा, तो इसके द्वारा बनाए गए त्रिकोण किनारे को साझा नहीं करेंगे - टोपोलॉजी खुली हो सकती है। – sum1stolemyname

उत्तर

3

किसी सरणी में सभी कोष्ठक डंप करें, फिर unique(sort(array)) करें। यह ओ (के एन लॉग (एन) होना चाहिए), जहां के त्रिभुजों की औसत संख्या है जो वर्टेक्स साझा करते हैं, आमतौर पर के < 7।

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

distance(vertex1, vertex2) < threshold 

लेकिन यह प्रतीत हो रहा है चाहता हूँ OK

+0

यह दृष्टिकोण काम करता है। मैंने एसटीएल सूची का उपयोग करके इसे लागू किया। +1 – sum1stolemyname

+0

और यह _much_ उस तरह से अधिक कुशल है। (मेरे पहले दृष्टिकोण के साथ 35 सेकंड, परिष्कृत दृष्टिकोण के साथ 1.5 सेकंड) – sum1stolemyname

+2

यदि आप एक दूसरे की दहलीज दूरी के भीतर अंक पकड़ना चाहते हैं तो इसमें एक बुरा बग है। इस बात की कोई गारंटी नहीं है कि अंक एक दूसरे के नजदीक "क्रमबद्ध" हो जाएं। असल में मुझे लगता है कि आप साबित कर सकते हैं कि किसी भी तरह के फ़ंक्शन के लिए अंक मनमाने ढंग से एक साथ बंद होते हैं जो सूची में दूरस्थ स्थानों पर क्रमबद्ध होते हैं ... अच्छा नहीं। –

2

तीन समाधान। निश्चित रूप से अन्य

  1. हैश मानचित्र का उपयोग करें। यह केवल तभी काम करेगा यदि "समान" का अर्थ बिल्कुल
  2. अंक
  3. को विभाजित करने के लिए बाइनरी स्पेस विभाजन का उपयोग करें, अपने बिंदुओं को विभाजित करने के लिए नियमित ग्रिड का उपयोग करें।

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

+0

यह मुझे थोड़ा सा ले गया कि अंतरिक्ष विभाजन कैसे मेरी मदद कर सकता है - यह एक दिलचस्प दृष्टिकोण है। +1 – sum1stolemyname

0

हैश प्राप्त करने का सामान्य विचार prime के साथ एक फ्लोट के प्रत्येक बिटपटल को गुणा करना है और उन्हें एक साथ जोड़ना है। ऐसा ही कुछ:

unsigned int hash_point(float x, float y, float z) 
{ 
    unsigned int* px = (unsigned int*)&x; 
    unsigned int* py = (unsigned int*)&y; 
    unsigned int* pz = (unsigned int*)&z; 

    return (*px)*PRIME1 + (*py)*PRIME2 + (*pz)*PRIME3; 
} 

आपको लगता है कि sizeof (अहस्ताक्षरित int) को ध्यान देना चाहिए sizeof (नाव) यहाँ के बराबर माना जाता है। यहां नमूना केवल मुख्य विचार को चित्रित करने के लिए है, आपको इसे अपनी आवश्यकताओं के लिए ट्यून करना चाहिए।

+0

जब एक्स, वाई और जेड पूर्णांक नहीं होते हैं, तो उन्हें प्राइम्स द्वारा गुणा करने से ज्यादा मदद नहीं मिलती है। – Tarydon

+0

सही। आपको फ्लोट्स के बिटपटर को गुणा करना चाहिए, न कि खुद तैरता है। –

+0

सावधान रहें कि कुछ संख्याओं में एक से अधिक बिट-पैटर्न प्रतिनिधित्व 0 और -0 समान हैं, फिर भी अलग-अलग बिट पैटर्न हैं। इसका मतलब है कि वे अलग-अलग मूल्यों के लिए हैश करेंगे। यद्यपि यह आपके आवेदन के लिए कोई समस्या हो सकती है या नहीं भी हो सकती है। –

संबंधित मुद्दे