2009-10-06 14 views
29

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

इनपुट: 2 डी में 2 बहुभुज (ए और बी), किनारों की सूची [(x0, y0, x1, y2), ...] की सूची के रूप में दिया गया है। अंक double एस के जोड़े द्वारा दर्शाए जाते हैं। मुझे नहीं पता कि उन्हें घड़ी की दिशा में, विपरीत दिशा में या किसी भी दिशा में दिया गया है या नहीं। मैं जानता हूं कि वे आवश्यक रूप से उत्तल नहीं हैं।

आउटपुट: ए, बी और अंतरंग बहुभुज एबी का प्रतिनिधित्व करने वाले 3 बहुभुज। इनमें से कोई भी खाली (?) बहुभुज हो सकता है, उदा। null

अनुकूलन के लिए संकेत: ये बहुभुज कमरे और मंजिल सीमाओं का प्रतिनिधित्व करते हैं। तो कमरे की सीमा आम तौर पर मंजिल सीमा से पूरी तरह से छेड़छाड़ की जाएगी, जब तक कि यह एक ही विमान (argh!) पर किसी अन्य मंजिल से संबंधित न हो।

मुझे आशा है कि किसी ने पहले से ही इसे सी # में किया है और मुझे अपनी रणनीति/कोड का उपयोग करने देगी, जैसा कि मैंने इस समस्या पर अब तक पाया है, बल्कि यह मुश्किल है।

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

आउटपुट: सबसे पहले बहुभुज शून्य से सभी अन्तर्विभाजक बिट्स, चौराहे बहुभुज (बहुवचन ठीक है)। मैं वास्तव में दूसरे बहुभुज में दिलचस्पी नहीं रखता हूं, केवल पहले के साथ इसका चौराहे।

EDIT2: मैं वर्तमान में GPC (General Polygon Clipper) लाइब्रेरी का उपयोग कर रहा हूं जो इसे वास्तव में आसान बनाता है!

+2

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

+3

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

+0

धन्यवाद, इसके बारे में कठिन सोचना होगा और समाधान के साथ आना होगा। इससे पहले इस तरह से नहीं सोचा था ... –

उत्तर

10

मुझे लगता है कि क्या करना चाहिए

अगर आप संभवतः यह मदद कर सकते हैं अपने आप को यह करने के लिए प्रयास न करें। इसके बजाय, पहले से मौजूद कई उपलब्ध बहुभुज चौराहे एल्गोरिदम का उपयोग करें।

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

http://www.cs.man.ac.uk/~toby/gpc/

मैं वास्तव में क्या एक बहुभुज-चौराहे एल्गोरिथ्म कि Java2D पुस्तकालयों का हिस्सा है उपयोग करने के लिए किया गया था। आप संभवतः एमएस के अपने सी # पुस्तकालयों में उपयोग करने के लिए कुछ समान खोज सकते हैं।

वहां अन्य विकल्प भी हैं; "पॉलीगॉन क्लिपर" या "बहुभुज क्लिपिंग" की तलाश करें, क्योंकि पॉलीगॉन चौराहे को संभालने वाले समान मूल एल्गोरिदम सामान्य क्लिपिंग मामलों के लिए उपयोग करने योग्य होते हैं।

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

अपने खुद के रोल कैसे बुरी masochistic

के लिए जब मैं अपने खुद के रोलिंग विचार कर रहा था, मैं सामान्य बहुभुज काटने के लिए सबसे अधिक क्षमता है वीलर-आथर्टन एल्गोरिथ्म पाया। मैं एक संदर्भ के रूप में निम्नलिखित प्रयोग किया है:

http://cs1.bradley.edu/public/jcm/weileratherton.html

http://en.wikipedia.org/wiki/Weiler-Atherton

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

यह वास्तव में काफी कार्यान्वित है, लेकिन किसी भी कम्प्यूटेशनल ज्यामिति कोड के साथ, शैतान अपमानजनक है।

+0

बस इसे फिर से देखा गया। मैं जीपीसी पुस्तकालय (शीर्ष लिंक) का उपयोग कर समाप्त हो गया। यह बढ़िया है। –

17

अरश पार्टो की FastGEO लाइब्रेरी में कम्प्यूटेशनल ज्यामिति में कई रोचक एल्गोरिदम के कार्यान्वयन शामिल हैं। बहुभुज चौराहे उनमें से एक है। यह पास्कल में लिखा गया है, लेकिन यह केवल गणित को लागू कर रहा है, इसलिए यह बहुत पठनीय है। ध्यान दें कि आपको निश्चित रूप से घड़ी के किनारे या घुमावदार क्रम में लाने के लिए, अपने किनारों को थोड़ा सा प्रीप्रोसेस करना होगा।

ईटीए: लेकिन वास्तव में, ऐसा करने का सबसे अच्छा तरीका यह है कि यह न करें। अपनी समस्या से संपर्क करने के लिए एक और तरीका खोजें जिसमें मनमानी बहुभुज चौराहे शामिल नहीं है।

+7

यदि आप ऐसा करते हैं, तो बहुत सावधान रहें और न बदलें मूल कोड से एल्गोरिदम का कुछ भी। यदि संभव हो, तो पास्कल-टू-सी कंपाइलर प्राप्त करें या इसे उस लाइब्रेरी में संकलित करें जिसका उपयोग आप स्वयं कोड का अनुवाद करने की कोशिश करने के बजाय कर सकते हैं। इसके लिए – jprete

2

आप NetTopologySuite पर भी एक नज़र डालना चाहते हैं या इसे एसक्यूएल सर्वर 2008 & में इसे स्थानिक टूल में आयात करने का प्रयास भी कर सकते हैं।

+0

+1। मैं जेटीएस के एक .NET बंदरगाह की तलाश में था, और ऐसा लगता है कि यह बिल फिट होगा। –

2

एक बहुभुज पूरी तरह से एक का आदेश दिया द्वारा वर्णित है अंक की सूची (पी 1, पी 2, ..., पीएन)। किनारों (पी 1 - पी 2), (पी 2 - पी 3), ..., (पीएन - पी 1) हैं। यदि आपके पास दो बहुभुज ए और बी हैं जो ओवरलैप होते हैं, तो एक बिंदु होगा (पॉलीगॉन ए का वर्णन करने वाले बिंदुओं की सूची से) जो बहुभुज बी या इसके विपरीत (बी का एक बिंदु बी में निहित) के क्षेत्र में स्थित है। यदि ऐसा कोई बिंदु नहीं मिलता है, तो बहुभुज ओवरलैप नहीं होता है। यदि ऐसा कोई बिंदु पाया जाता है (यानी एआई) बहुभुज ए (i-1) और ए (i + 1) के आसन्न बिंदुओं की जांच करें। तब तक दोहराएं जब तक आप क्षेत्र के बाहर कोई बिंदु नहीं ढूंढते या सभी बिंदुओं की जांच नहीं की जाती है (फिर पहला बहुभुज दूसरे बहुभुज के भीतर पूरी तरह से निहित होता है)। यदि आपको बाहर एक बिंदु मिलता है तो आप क्रॉसिंग पॉइंट की गणना कर सकते हैं। बहुभुज बी के संबंधित किनारे को ढूंढें और पुनर्वित्त वाली भूमिकाओं के साथ इसका पालन करें = अब जांच करें कि बहुभुज बी के बिंदु बहुभुज ए के भीतर हैं या नहीं। इस तरह आप ओवरलैपिंग बहुभुज का वर्णन करने वाले बिंदुओं की एक सूची बना सकते हैं। यदि आवश्यक हो तो आपको जांच करनी चाहिए कि क्या बहुभुज समान हैं, (पी 1, पी 2, पी 3) === (पी 2, पी 3, पी 1)।

यह सिर्फ एक विचार है और शायद बेहतर तरीके हैं। आप एक काम कर पाते हैं और समाधान का परीक्षण किया, तो मैं सुझाव है कि आप इसका इस्तेमाल ...

narozed ऐसे ArcObjects, TopologySuite, GEOS, OGR, आदि के रूप में उस के लिए जीआईएस उपकरण, का उपयोग करने के

2

कोशिशमुझे यकीन नहीं है कि ये सभी वितरण .NET के लिए उपलब्ध हैं, लेकिन वे सभी समान हैं।

+1

एफवाईआई, ओजीआर (जीडीएएल/ओजीआर से) जीईओएस (http://trac.osgeo.org/geos/) लाइब्रेरी का उपयोग करता है, इसलिए इन दोनों के बीच कम्प्यूटेशनल ज्यामिति के कार्यान्वयन के संबंध में कोई अंतर नहीं है। – mloskot

+0

humn, जानना अच्छा है :) –

11

आप .नेट फ्रेमवर्क में प्रोग्रामिंग रहे हैं, तो आप एक के रूप में Microsoft SQL Server System CLR Types

SqlGeometry वर्ग STIntersection तरीका प्रदान करता है भेज दिया .NET विधानसभाओं में उपलब्ध SqlGeometry वर्ग पर नज़र रखना कर सकते हैं

SqlGeometry g1 = SqlGeometry.Parse("POLYGON ((...))"); 
SqlGeometry g2 = SqlGeometry.Parse("POLYGON ((...))"); 
SqlGeometry intersection = g1.STIntersection(g2); 
+3

क्या यह उत्तर गलत है, तो यह डाउनवोट हो गया? यदि ऐसा है, तो कृपया एक बग कहां इंगित करें। – mloskot

+1

मैं सहमत हूं! इस समाधान के साथ क्या गलत है? मैं व्यक्तिगत रूप से डीबी में अपनी सभी स्थानिक चीजें करता हूं ... लेकिन अगर आपको कोड में ऐसा करने की ज़रूरत है, तो उसी कोड का लाभ उठाएं :) –

2

क्लिपर है ओपन सोर्स फ्रीवेयर पॉलीगॉन क्लिपिंग लाइब्रेरी (डेल्फी और सी ++ में लिखी गई) जो आप पूछ रहे हैं - http://sourceforge.net/projects/polyclipping/

मेरे परीक्षण में, क्लिपर जीपीसी की तुलना में त्रुटि के लिए काफी तेज और बहुत कम प्रवण है (यहां अधिक विस्तृत तुलना देखें - http://www.angusj.com/delphi/clipper.php#features)। साथ ही, डेल्फी और सी ++ दोनों के लिए स्रोत कोड होने पर, क्लिपर लाइब्रेरी में एक संकलित डीएलएल भी शामिल है ताकि अन्य (विंडोज) भाषाओं में क्लिपिंग फ़ंक्शंस का उपयोग करना बहुत आसान हो।

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