2011-02-18 19 views
7

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

तो अब समस्या यह है कि मैं इस सूची में पुनरावृत्ति करते समय पॉलीगॉन के "बाहर के बाहर" बिंदुओं की सूची को क्रमबद्ध करने का एक तरीका ढूंढना चाहता हूं।

या मैटलप्लिब में कुछ अन्य कार्यक्षमता हो सकती है जो मेरे लिए यह कर सकती है?

उत्तर

4

जैसा कि सभी तैयार एक सरल समाधान है कि कुछ आंतरिक बिंदुओं से कोणों की गणना सभी बिंदुओं पर करें और उन्हें क्रमबद्ध करें।

तो यहाँ आप के लिए गणना करने के लिए एक numpy समारोह है ccworder:

In []: def ccworder(A): 
    ..:  A= A- mean(A, 1)[:, None] 
    ..:  return argsort(arctan2(A[1, :], A[0, :])) 
    ..: 

और सरल प्रदर्शन:

In []: A 
Out[]: 
array([[0, 0, 1, 1], 
     [0, 1, 1, 0]]) 
In []: ccworder(A) 
Out[]: array([0, 3, 2, 1]) 

अद्यतन:
यह लग सकता है इस तरह का आदेश देने की किसी भी तरह हो सकता है कि गणना करने के लिए कठिन, लेकिन numpy उन्हें बहुत सरल बनाने के लिए अच्छा abstraction प्रदान कर सकते हैं।

चेतावनी: के रूप में जो और अन्य लोगों ने बताया है, इस ccworder उत्तल पतवार सभी बिंदुओं सभी उत्तल पतवार पर तैयार कर रहे हैं केवल यदि पर उचित क्रम बनेगी। अर्थात। किसी भी तरह से ऑर्डर गायब है, क्योंकि यह ओपी का मामला प्रतीत होता है, इसे पुनर्प्राप्त किया जा सकता है। अन्य स्थितियों में ccworder का उपयोग किया जाता है।

+1

साधारण मामलों के लिए, यह निश्चित रूप से जाने का तरीका है (+1)। यदि वह अंक हमेशा एक उत्तल हलचल बनाते हैं, तो यह हमेशा काम करेगा। हालांकि, आप यह इंगित करना चाहेंगे कि यह अधिक जटिल बहुभुजों के लिए काम नहीं करेगा (यानी कुछ भी जहां बिंदुओं का "सही" क्रम बस केंद्र के बारे में लगातार बढ़ता कोण नहीं है)। –

2

मुझे मैटलप्लॉटिब नहीं पता है, लेकिन आपको जो चाहिए/चाहिए वह बिंदु सेट के को आकर्षित करना है। कन्वेंक्स हॉल को एक लोचदार रस्सी के रूप में सोचें जो आप बिंदु सेट के चारों ओर रखते हैं। लोचदार रस्सी पर आकृति का आकार उत्तल हैल। उत्तल हॉल की गणना के लिए अलग-अलग एल्गोरिदम हैं, इसलिए जांच करें कि Matplotlib किसी का समर्थन करता है या नहीं। यदि नहीं, तो इन लिंक को एक कार्यान्वित बिंदु के लिए जांचें कि एक को कैसे कार्यान्वित किया जाए।

http://en.wikipedia.org/wiki/Convex_hull

http://en.wikipedia.org/wiki/Convex_hull_algorithms

+0

धन्यवाद। लेकिन जहां तक ​​मैं इसे समझता हूं, "उत्तल हल ढूंढना" आमतौर पर उन बिंदुओं का सबसेट ढूंढना है जो कुल सेट के उत्तल झुंड का हिस्सा हैं। – Eskil

+0

धन्यवाद। लेकिन जहां तक ​​मैं इसे समझता हूं, "उत्तल हल ढूंढना" आमतौर पर उन बिंदुओं का सबसेट ढूंढना है जो कुल सेट के उत्तल झुंड का हिस्सा हैं। दूसरी ओर, मुझे पहले से ही कुछ अर्थों में उत्तल झुकाव है, मुझे बस उन्हें आदेश देने की आवश्यकता है कि जब मैं उनके बीच रेखा खींचता हूं तो मुझे उत्तल हलचल का चित्र मिलता है। – Eskil

1

यहाँ आप उत्तल पतवार की एक अजगर कार्यान्वयन है (यह आपके लिए क्या देख रहे है):

http://www.scipy.org/Cookbook/Finding_Convex_Hull

+0

समस्या यह है कि इस एल्गोरिदम के लिए आवश्यक है कि मेरे पास पांच से अधिक अंक हैं। मुझे कुछ ऐसे चीजों की ज़रूरत है जो साधारण मामलों के लिए काम करती हैं। यह भी बहुत अधिक है, क्योंकि मेरे पास पहले से ही सेट है जो उत्तल हल है, मुझे इसे खींचने में सक्षम होने के लिए इसे सही ढंग से सॉर्ट करने की आवश्यकता है। – Eskil

2

आप पहले से ही पतवार अंक पता है, फिर उन बिंदुओं को जोड़कर बहुभुज को चित्रित करना वास्तव में Matplotlib में करना बहुत आसान है क्योंकि बहुभुज लागू होते हैं पथ के रूप में Matplotlib में ted। मैं matplotlib.path class से शुरू करूंगा।

यदि आप हल बिंदुओं को नहीं जानते हैं तो मैं एल्मर से सहमत हूं - उत्तल हॉल आपके द्वारा इच्छित एल्गोरिदम है। मैंने NumPy में इस एल्गोरिदम को कोड किया है और इसे Matplotlib में प्लॉट किया है। मेरा कोड साइपी कुकबुक, here में एक उत्कृष्ट नुस्खा से उधार लिया गया था। इस नुस्खा में एक NumPy कार्यान्वयन और अंक के दिए गए सेट के आसपास उत्तल होल में Matplotlib में साजिश के लिए आवश्यक पूरा कोड शामिल है।

इसके अतिरिक्त, मैटलप्लिब में delauney नामक एक पैकेज शामिल है, जैसा कि आपने अनुमान लगाया है कि डेलाउन त्रिभुज का उपयोग करके सतह को टेसलेट करने के लिए है। और जैसा कि आप जानते हैं, यह voronoi tesselation के माध्यम से उत्तल हल से संबंधित है - यानी, प्रत्येक voronoi सेल की सीमाओं को उत्तल झुकाव गणना से बनाया गया है।

+0

लेकिन चूंकि मेरे पास पहले से ही उत्तल हल बिंदु सेट है, यह अधिक हो सकता है। मुझे बस उन्हें सॉर्ट करने की आवश्यकता है ताकि वे घड़ी की दिशा में या घुमावदार क्रम में आ सकें। और आपके लिंक में एल्गोरिदम 6 अंक से कम नहीं लेगा। – Eskil

+1

डेलाउनी एक उत्तल बहुभुज त्रिभुज के लिए बल्कि अधिक है। इसके बजाय बस एक त्रिकोण प्रशंसक का उपयोग करें। हालांकि, यदि आप आंतरिक बिंदुओं सहित त्रिभुज करना चाहते हैं, तो Delauney का उपयोग करें। –

2

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

2

फिर, सॉर्टिंग स्वयं कैसे करें?

कहो, उत्तल पतवार बिंदु सेट एक सूची अंक अजगर में, और सी अपने उत्तल पतवार बिंदु सेट में आंतरिक बिंदु के कुछ प्रकार है, तो आप सिर्फ निम्नलिखित छद्म की तरह एक comparer तैयार कर सकते हैं के रूप में संग्रहीत किया जाता है -code:

def cmpAngle(p1, p2): 
    vector1 = p1 - C 
    vector2 = p2 - C 
    return dotProduct(vector1, vector2) 
points.sort(cmp=cmpAngle) 

विचार डॉट उत्पाद का उपयोग करने के लिए उनके रिश्तेदार रोटेशन से आदेश देने के यह पता लगाने की है।

0

मैंने इस तरह की समस्या के लिए scipy.spatial का उपयोग किया है। उत्तल उत्थान की साजिश के लिए इसमें विशिष्ट कार्य हैं। here देखें। हो सकता है कि आप चाहते थे की तुलना में अधिक अग्निशक्ति है।