एक अनियमित आकार के क्षेत्र की गणना कैसे करें?


17

मेरे पास लूपिंग लाइन सेगमेंट के संग्रह द्वारा परिभाषित एक कमरा ऑब्जेक्ट है जिसे मुझे उस क्षेत्र की गणना करने की आवश्यकता है। वर्गों को निम्नानुसार वर्णित किया जा सकता है (छद्म कोड में):

class Point {
    float x; 
    float y;
    ...
    float distanceFrom(Point p);
}

class Segment {
    Point start;
    Point end;
    ...
    float length();
}

class Room {
    List<Segment> walls;
    ...
    float area();
}

एक कमरे की दीवारें कभी भी कहीं भी घुस नहीं सकती हैं, लेकिन सेगमेंट के अंतिम बिंदु पर और बनाए गए किसी भी "सब-लूप" को भी एक नए कमरे में अलग कर दिया जाएगा। समाधान पूरी तरह से सटीक होने की आवश्यकता नहीं है (त्रुटि का 10% मार्जिन स्वीकार्य है) और बहुत बार गणना नहीं की जाती है (<1 / s)।


7
यह एस Roomकी एक सूची को शामिल करने के लिए और अधिक समझ में आता है Point, और फिर प्रत्येक बिंदु को एक साथ जोड़कर खंड प्राप्त करता है और फिर इसे वापस चारों ओर लूप करता है। अन्यथा, आपके वर्तमान सेटअप के साथ, गलत मान प्राप्त करने के लिए यह बहुत पूरब है (जैसे कि अप्रयुक्त कमरा, बीच में दीवार के साथ कमरा, आदि)। यह सबसे अच्छा विकल्प होगा।
MCMastery

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

@MCMastery यह समाधान काम नहीं करेगा, क्योंकि इसके Roomलिए हमेशा पूर्ण होने की आवश्यकता होती है , और ऐसा नहीं हो सकता है अगर मेरे पास खिलाड़ी का Roomउपयोग कर रहा है Segment। इसके अलावा, एक बंद कमरे के कार्य को परिभाषित करना आसान है ( Segmentएस के माध्यम से सिर्फ लूप और सुनिश्चित करें कि वे एक कमरा बनाते हैं)।

जवाबों:


31

आप गॉस के फावड़े के फार्मूले का उपयोग कर सकते हैं :

आपको हर बिंदु के x निर्देशांक को लेने की जरूरत है, उन्हें अगले बिंदु के y निर्देशांक से गुणा करें, फिर वर्तमान बिंदु के y को घटाएं अगले बिंदु x के गुणन को परिणाम से गुणा करें और उन्हें कुल क्षेत्रफल में जोड़ें। आपके द्वारा हर बिंदु के लिए ऐसा करने के बाद, कुल क्षेत्रफल को बहुभुज का वास्तविक क्षेत्र प्राप्त करने के लिए आधा कर दें। यदि वर्तमान बिंदु अंतिम है, तो अगला पहला है।

A = 0

for (i = 0; i < points.length; i++) do

    A += points[i].x * points[(i + 1) % points.length].y - points[i].y * points[(i + 1) % points.length].x

end

A /= 2

2
मैंने हमेशा इस्तेमाल किया कि दो वैक्टरों के क्रॉस उत्पाद की गणना करने के लिए यह कभी नहीं जाना जाता था कि इसे
शॉलेज़

3
ध्यान दें कि यह त्रिकोण से बने एक अनियमित 3 डी वस्तु की मात्रा की गणना करने के लिए बढ़ाया जा सकता है, और इसे पथरी के मौलिक प्रमेय का एक तुच्छ मामला माना जा सकता है।
डिट्रीच एप्प

5
यहां का क्षेत्र हस्ताक्षरित है। अन्य दिशा में अंकों के माध्यम से जाओ और अंतिम Aनकारात्मक है। लक्ष्य के आधार पर A = |A|जरूरत पड़ सकती है। नकारात्मक क्षेत्र के साथ अंक के अंदर और बाहर की सूची (विपरीत क्रम में एक) का उपयोग करके अनियमित डोनट पर क्षेत्र पा सकते हैं।
chux -

6
बेशक या तो गॉस या यूलर के पास इसके लिए एक फार्मूला है।
corsiKa

0

हम एक मोंटे कार्लो विधि का भी उपयोग कर सकते हैं।

मनमाना आकार के चारों ओर एक आयत बनाएं। समान रूप से वितरित PRNG स्रोत को लें। mersenne ट्विस्टर, फिर आयत के X, Y लंबाई को मोडुलो फ़ंक्शन का उपयोग करके आउटपुट को बाध्य करता है। गिनती नं। यादृच्छिक-बिंदु जो आपके आकार के अंदर आते हैं। उत्पन्न अंकों की कुल राशि से विभाजित करें। आयत के क्षेत्र से उस भाग को गुणा करें। प्रत्येक पुनरावृत्ति के साथ आप वास्तविक क्षेत्र में परिवर्तित हो जाएंगे। एल्गोरिथ्म हास्यास्पद रूप से पैरेलेलेबल है और इसका उपयोग मनमाना आयामी आकार 'वॉल्यूम' की गणना करने के लिए किया जा सकता है, जब तक कि आप यह निर्धारित कर सकते हैं कि क्या R ^ N समन्वय आकार के R ^ N सीमा के भीतर आता है।

यहाँ कोई इस पद्धति का उपयोग कर सर्कल क्षेत्र ढूंढ रहा है, फिर उपयोग करता है कि pi https://www.youtube.com/watch?v=VJTFfIqO4TU की गणना करें


2
-1: आप इसे रेंज में लाने के लिए मोडुलो का उपयोग नहीं करना चाहते हैं, आप एक समान वितरण या अन्य वितरण का उपयोग करना चाहते हैं, यह करने के लिए मोडुलो तरीके से सभी प्रकार के सांख्यिकीय मुद्दे हैं।
221 पर user1997744

12
यह विधि तब लाभदायक हो सकती है जब हमारे पास एक साधारण बहुभुज नहीं होता है, बल्कि कुछ प्रकार के निहित आकार होते हैं जिनकी सीमा को व्यक्त करना मुश्किल होता है, जैसे भग्न या मेटाबॉल बूँद। बहुभुज के मामले के रूप में सवाल में हालांकि, ऐसा लगता है कि यह अनावश्यक रूप से महंगा होगा।
DMGregory

जैसा कि @DMGregory ने बताया, यह वह नहीं है जिसकी मुझे तलाश थी। हालाँकि, मुझे लगता है कि यह किसी और के लिए आवश्यक होने पर +1 योग्य है।

यह दिलचस्प है लेकिन समावेशन परीक्षणों की लागत निषेधात्मक नहीं होगी? यानी यदि आपके पास एक आकार है जो इस दृष्टिकोण को वारंट करने के लिए पर्याप्त रूप से जटिल है, तो क्या समावेश परीक्षण भी वास्तव में महंगा नहीं होगा, इसलिए आप उन्हें टन नहीं करना चाहेंगे? (मान लेते हैं बहुभुज)
मटिया

ठीक है modulo वास्तव में समस्याग्रस्त है, लेकिन यह एक सरल समाधान है। जो हमें सही मायने में मिलता है वह है यादृच्छिक P = 1/2 बिट्स 0/1, इसलिए हमें जो मिलता है वह संख्याओं का एक समान वितरण है। 3 बिट्स के लिए 0 से 7. तक रैंड% 5 करना, यदि एक यादृच्छिक संख्या 6 या 7 मान लेती है, तो 1 या 2 से मैप किया जाता है, प्रभावी रूप से वितरण को गैर-वर्दी बनाते हुए 1,2 आवृत्ति बढ़ जाती है। इससे बचने के लिए आपको एक राज्य मशीन की तरह कुछ चाहिए जो मानचित्रण को घुमाती है। 6,7 के नक्शे 1,2 फिर 3,4 फिर 5,0 और यह चला जाता है। जब भी वे आते हैं हम 6,7 फेंक सकते हैं। वैसे भी यह एक पुस्तकालय कार्यान्वयन समस्या है।
19

-1

एक और दृष्टिकोण: नहीं।

बजाय:

while (Segments.Count > 3)
{
    Segment A = Segments[Segments.Count - 2];
    Segment B = Segments[Segments.Count - 1];
    Segment C = new Segment(B.End, A.Start);
    Triangle T = new Triangle(A, B, C);
    Segments[Segments.Count - 2] = C;
    Segments.RemoveAt(Segments.Count - 1);
    if (B is inside the new shape Segments)
        Area -= T.Area;
    else
        Area += T.Area;
}
Area += new Triangle(Segments[0], Segments[1], Segments[2]).Area;

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


2
गॉस का शॉलेस फॉर्मूला इसके लिए एक शॉर्टहैंड है जो गणना की संख्या को आधा या तिहाई कर देता है। इसका हल करना।
पीटर गेकर्न्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.