दक्षिणावर्त क्रम में बिंदुओं की छंटाई सरणी


16

क्या दक्षिणावर्त क्रम में 2 डी बिंदुओं की एक सरणी को सॉर्ट करने के लिए ऐसा एल्गोरिथ्म है?
मैं विशेष रूप से अपने मामले में सही त्रिकोण के साथ काम कर रहा हूं इसलिए केवल 3 अंक।

हालाँकि मुझे यह जानने में दिलचस्पी है कि क्या ऐसा एल्गोरिथ्म मौजूद है, यदि नहीं, तो मेरे त्रिकोण के 3 बिंदुओं को दक्षिणावर्त क्रम में वापस करने का एक सरल तरीका क्या है?

संपादित करें: मैं बहुभुज के केंद्रक के सापेक्ष दक्षिणावर्त बिंदुओं की गणना करने की कोशिश कर रहा हूं, जो उत्तल है।

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

ArrayList<PVector> pointList = new ArrayList<PVector>();
pointList.add(A);
pointList.add(B);
pointList.add(C);
Collections.sort( pointList, new TriangleVectorComparator(origin) );

return pointList;

// Comparator
package triangleeditor;

import java.util.Comparator;

import processing.core.PVector;

public class TriangleVectorComparator implements Comparator<PVector>  {
    private PVector M; 
    public TriangleVectorComparator(PVector origin) {
        M = origin;
    }

    public int compare(PVector o1, PVector o2) {
        double angle1 = Math.atan2(o1.y - M.y, o1.x - M.x);
        double angle2 = Math.atan2(o2.y - M.y, o2.x - M.x);

        //For counter-clockwise, just reverse the signs of the return values
        if(angle1 < angle2) return 1;
        else if (angle2 < angle1) return -1;
        return 0;
    }

}

1
वापसी कोण 1 <कोण 2 हो सकता है? 1: एंगल 2> एंगल 1? -1: 0;
ademar111190

2
इसे कई तरह से व्यक्त किया जा सकता है, लेकिन मैं उदाहरण देते समय नेस्टर्ड टर्नरी ऑपरेटरों से बचने की प्रवृत्ति रखता हूं।
onedayitwillmake 19

@onedayitwillmake क्या आप उस कोड को स्थानांतरित कर सकते हैं जिसे आपने उत्तर में उपयोग करके समाप्त किया था? यह वास्तव में सवाल में नहीं है, लेकिन यह भविष्य के पाठकों के लिए बहुत मूल्यवान है।
एको

@ अको मुझे लगता है कि आप सही हैं, लेकिन साथ ही मुझे लगता है कि लोगों के लिए इसे इस तरह से ढूंढना सबसे आसान होगा। यह यह भी सुनिश्चित करने में मदद करता है कि मैं samhocevar के जवाब से दूर नहीं हूं जो मेरा बस पर आधारित है।
onedayitwillmake 22

जवाबों:


19

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

दक्षिणावर्त या एंटीक्लॉकवाइज

आपके मामले में, मेरा मानना ​​है कि संदर्भ बिंदु के रूप में बिंदुओं के बायर्सेंट का उपयोग करना उचित है।

अज्ञात संख्या के लिए एक अच्छी विधि निम्नलिखित हो सकती है:

  • जाने P[0], P[1], ... P[n-1]प्रकार के अंकों की सूची हो
  • आज्ञा देना सभी बिंदुओं के barycenter हो
  • a[0], a[1], ... a[n-1]इस तरह की गणना करेंa[i] = atan2(P[i].y - M.y, P[i].x - M.x);
  • उदाहरण के लिए aउपयोग करते हुए, उनके मूल्य के सापेक्ष अंक qsort

हालांकि, आप यह सुनिश्चित कर सकते हैं कि एक अच्छा छँटाई एल्गोरिथ्म एक तदर्थ विधि की तुलना में तीन इनपुट मूल्यों के साथ खराब प्रदर्शन करेगा। उपयोग करना atan2अभी भी मान्य है, लेकिन अभी उपयोग न करें qsort


इसने पूरी तरह से काम किया :)
onedayitwillmake

1
क्या इस विधि का कोई नाम है?
onedayitwillmake

1
मेरा मानना ​​है कि इसे "ध्रुवीय कोण द्वारा छँटाई" कहा जाता है। उदाहरण के लिए, यह ग्राहम स्कैन का एक घटक है ।
सम होसीवर

यहां का प्रदर्शन हिट की qsortतुलना में छोटा है atan2

छोटे चेतावनी: इस संभावित दुर्घटना और जला (प्रोग्रामिंग भाषा और पुस्तकालयों के लिए इस्तेमाल किया पर निर्भर करता है) अंक के किसी भी वास्तव में होना करने के लिए होता है अगर होगा पर barycentre (या जो भी अन्य बिंदु उन्मुखीकरण के आप का उपयोग करें)। आप दूसरे और तीसरे चरण के बीच ऐसे बिंदुओं को बाहर करना चाह सकते हैं।
मार्टिन सोज्का

3

मेरा मानना ​​है कि जो आप वास्तव में यहां पूछ रहे हैं वह त्रिकोण का घुमावदार क्रम है, जो वास्तव में परीक्षण के लिए बहुत सरल है।

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

यहां सामान्य विचार है, यह मानते हुए कि त्रिभुज के तीन कोने एक , बी , और सी हैं , और आपके पास एक सरल वेक्टर उपप्रकार ऑपरेशन है:

Vector2 AToB = b - a;
Vector2 BToC = c - b;
float crossz = AToB.x * BToC.y - AToB.y * BToC.x;
if ( crossz > 0.0f )
{
  // clockwise
}
else
{
  // counter-clockwise.  Need to reverse the order of our vertices.
}

ध्यान दें कि आपने अपने + y अक्ष (ऊपर या नीचे) को किस तरह से उन्मुख किया है, इस पर "क्लॉकवाइज" और "काउंटर-क्लॉकवाइज" मामलों को उल्टा किया जा सकता है कि मैंने उन्हें इस नमूना कोड में टिप्पणियों में कैसे लेबल किया है।


मुझे बहुभुज बनाने के लिए Box2D (जावा कार्यान्वयन) के लिए इन बिंदुओं को पारित करने की आवश्यकता है। हालाँकि यह वह नहीं है जो मैं पूछ रहा था, बहुत अच्छी अंतर्दृष्टि :)
onedayitwillmake

2

क्या आप अधिक जानकारी दे सकते हैं? आप बिंदुओं का CCW क्रम चाहते हैं, लेकिन किस बिंदु पर क्रम का केंद्र होना चाहिए?

यदि आपके पास समतल में त्रिभुज (3 अंक) है, तो आप मैट्रिक्स से निर्धारक की गणना कर सकते हैं, जहां रेखाएं बिंदुओं का निर्देशांक हैं (तीसरा समन्वय 1 है)। यदि निर्धारक> 0 है, तो अंक CCW क्रम में हैं। यदि नहीं, तो आप पिछले दो बिंदुओं पर उदाहरण के लिए स्वाइप कर सकते हैं और आपको CCW ऑर्डर मिलेगा।

यदि आपके पास A, B, C अंक हैं, तो आपका मैट्रिक्स जैसा दिखता है:

|xA, yA, 1|
|xB, yB, 1|
|xC, yC, 1|

नियतांक है: xA * yB + xB * yC + xC * yA - yB * xC - yC * xA - yA * xB। फिर आप इसकी तुलना शून्य से कर सकते हैं। यदि यह 0 है, तो रिटर्न ए, बी, सी, यदि यह नहीं है, तो ए, सी, बी लौटाएं।

यदि आपके पास अंक हैं और जानते हैं, तो वे उत्तल बहुभुज बनाते हैं (सभी उत्तल पतवार का हिस्सा हैं), और उनका क्रम प्राप्त करना चाहते हैं, आप ग्राहम स्कैन या जार्विस मार्च का उपयोग कर सकते हैं (ये कई बिंदुओं से उत्तल खंभा खोजने के लिए एल्गोरिदम हैं, लेकिन यह भी यहाँ काम करना चाहिए :))


zacharmarz ने जो कहा उसे पूरा करने के लिए यदि आप किसी विशिष्ट बिंदु के चारों ओर अपने बिंदुओं को दक्षिणावर्त क्रम में क्रमबद्ध करना चाहते हैं, तो आप फ्लोट और जोड़े के जोड़ से एक सरणी बना सकते हैं, जिसमें आप उस विशिष्ट बिंदु से उनके अंकन कोण के साथ सभी बिंदुओं को संग्रहीत करते हैं, और फिर क्रमबद्ध करते हैं वह सरणी।
अली
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.