मैं कैसे बता सकता हूं कि कोई ऑब्जेक्ट कनेक्टेड पथ के आसपास CW या CCW घूम रहा है या नहीं?


19

कहते हैं कि हमारे पास एक दांतेदार आकार है:

shape0

और इसके साथ घूमने वाले दो जीवों की रूपरेखा है।

फिर हम कोनों को बाहर खींचकर आकार को पूरी तरह से चिकना करते हैं।

हमें यह मिलता है:

चिकनी

अब यह देखना आसान है कि ऑरेंज सीडब्ल्यू और हरे सीसीडब्ल्यू को स्थानांतरित कर रहा है। मैं यह कैसे बता सकता हूं कि वे किस दिशा में आकार को सुचारू किए बिना आगे बढ़ रहे हैं।

नया चित्र

यहाँ छवि विवरण दर्ज करें


यहाँ मेरे 2 सेंट है: i.imgur.com/zrBdw.png
केंडल फ्रे

जवाबों:


27

अनंत तक एक रेखा खींचें और गिनें कि आप कितनी बार आकृति (यहां तक ​​कि विषम) को पार करते हैं, न कि उस खंड को गिनते हुए जहां प्राणी झूठ बोलता है। फिर जांचें कि क्या प्राणी उस रेखा के बाएं या दाएं जा रहा है।

उदाहरण

इस उदाहरण में, हम दो बार आकृति को पार करते हैं (इसलिए भी) और हम बाईं ओर जाते हैं। परिणाम इस तालिका से तत्काल है:

   # Crosses | even  | odd
  Direction  |       |
-------------+-------+------
    left     | CCW   |  CW
    right    |  CW   | CCW

छद्मकोश में:

x, y = position of creature
vx, vy = direction of creature movement
crossings = 0
for each x1, y1, x2, y2 in shape segments:
    if (x1 < x and x <= x2) or (x2 < x and x <= x1):
        if y - y1 > (x - x1) * (y2 - y1) / (x2 - x1):
            ++crossings
if (crossings & 1) == (vx < 0):
    return CW
else
    return CCW

क्या आप आगे बढ़ने वाले लाइन प्राणी को शामिल करते हैं?
अली

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

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

@TrevorPowell सच। सबसे दूर का किनारा खोजना भ्रामक हो सकता है। मैंने सबसे पहले किनारे की सबसे दूर की चोटी पर आधारित जाँच की और फिर मैंने आकृति के केंद्र से एक रेखा खींचकर और दो किनारों के केंद्रों (दो जो कि शीर्ष साझा करते हैं) के माध्यम से और यह देखने के लिए कि क्या लाइनों में से एक दूसरे किनारे को पार करता है इन किनारों में से एक को पार करने के बाद अनंत। यह ठीक काम किया
wolfdawn

5

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


एक बहुत सरल समाधान, और मेरा पहला विचार भी।
Amplify91

आपको कैसे पता चलेगा कि आकृति किस दिशा में है? मेरा मतलब है कि आकृति के अंदर एक किनारे के साथ बढ़ना या तो आपके बाएं या आपके दाईं ओर है। आप कैसे जानते हैं कि यह कौन सा तरीका है?
अली

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

4
  1. अपने आकार के केंद्र बिंदु की गणना करें।
  2. केंद्र से अपने आकार का सबसे दूर का किनारा चुनें।
    • (सबसे दूर के किनारे को उठाते हुए यह सुनिश्चित करता है कि आप आकार के एक उल्टे, अवतल भाग से शुरू नहीं करते हैं, जिसके परिणामस्वरूप संपूर्ण आकार के लिए दक्षिणावर्त / एंटीक्लॉकवाइज़ दृढ़ संकल्प प्राप्त होता है)
  3. निर्धारित करें कि उस किनारे के साथ कौन सी दिशा दक्षिणावर्त है
    • (इसका एक सरल क्रियान्वयन आकार के केंद्र से कोणों की तुलना चयनित किनारे के प्रत्येक छोर पर करना होगा। कोणों के बीच अंतर का संकेत आपके दक्षिणावर्त बनाम काउंटर-क्लॉकवाइज को बताएगा)
  4. आकृति के सभी किनारों पर फेरबदल करें, चरण 2 में आपके द्वारा उठाए गए किनारे से शुरू होकर किनारों की सूची का निर्माण। प्रत्येक किनारे के लिए, घड़ी की दिशा में इसके दो कोने स्टोर करें।
    • (यदि आपका आकार समय के साथ नहीं बदल रहा है, तो आप इस एज लिस्ट को बाद में उपयोग के लिए स्टोर कर सकते हैं, इसलिए आपको हर फ्रेम के पहले चार हिस्से नहीं करने होंगे)
    • (आपके पास पहले से ही एक बढ़त सूची हो सकती है। यदि हां, तो आप उसी सूची में इस दक्षिणावर्त शीर्ष क्रम को संग्रहीत कर सकते हैं।)
  5. यह निर्धारित करने के लिए कि कोई इकाई दक्षिणावर्त घूम रही है या एंटीक्लॉकवाइज:
    • निर्धारित करें कि इकाई किस किनारे के साथ आगे बढ़ रही है।
    • वेक्टर के खिलाफ आंदोलन की दिशा की दिशा का एक डॉट उत्पाद करें, जो उस छोर से दक्षिणावर्त शुरू होता है-> अंत लंबवत जो आपने चरण 4 में वापस निर्धारित किया था।
    • यदि डॉट उत्पाद का परिणाम शून्य से अधिक मूल्य है, तो इकाई दक्षिणावर्त चलती है। शून्य से कम का अर्थ है एंटीक्लॉकवाइज।

बहुत ही चतुर उत्तर
wolfdawn

मुझे थोड़ा सवाल आया है? यह मानते हुए कि उनके उत्तर में सबसे बाएं बिंदु CWW से शुरुआत की जा रही है, मैं आपके उत्तर के आधार पर बता सकता हूं कि 6-> 7 या 9-> 10 (शून्य आधारित) से चलते हुए घड़ी की दिशा में कैसे चल रहा है?
अली

आप सबसे दूर के किनारे से शुरू करते हैं, और यह पता लगाते हैं कि उस किनारे पर कौन सा रास्ता दक्षिणावर्त है। मान लीजिए कि किनारे A, 'a' से 'b' तक के वर्चस्व से दक्षिणावर्त है। फिर यदि हम B को किनारे पर ले जाते हैं (जिसमें कोने 'b' और 'c') हैं, तो हम जानते हैं कि B 'b' से 'c' तक दक्षिणावर्त है। इसी तरह, एज C, 'c' से 'd' तक क्लॉकवाइज होने वाला है। एक बार जब हम एक किनारे से सही दक्षिणावर्त दिशा (1-3 कदम) जानते हैं, तो आकार के किनारों के आसपास उस दक्षिणावर्त दिशा में जारी रखकर हम हर किनारे के लिए सही 'दक्षिणावर्त' दिशा को घटा सकते हैं, वास्तव में यह देखने के बिना कि इसके किनारे कहाँ स्थित हैं, इतनी सहमति ठीक है।
ट्रेवर पावेल

आप यह कैसे बता सकते हैं कि एज ए 'ए' से 'बी' तक की घड़ी की दिशा में है या अगर यह 'बी' से 'ए' के ​​लिए क्लॉकवाइज है? मुझे लगता है कि आप उस हिस्से से चूक गए।
अली

@ Gajoo यह चरण 3 पर मूल बिंदु है। संभवत: यह मूल प्रक्रिया नहीं होनी चाहिए, क्योंकि यह पूरी प्रक्रिया का महत्वपूर्ण चरण है।
ट्रेवर पावेल

2

आपको यह जानने की जरूरत है कि बहुभुज को किस तरीके से परिभाषित किया गया है, किस तरह से वर्टिकल इसे गोल करते हैं।

यदि आपको इसकी जानकारी नहीं है, तो आप इसे बहुभुज के क्षेत्रफल की गणना करके काम कर सकते हैं:

float Polygon::area() {
    float result = 0.0f;

    for(int a = 0; a < vertexCount; a ++) {
        int b = (a+1) % vertexCount;
        result += vertices[a].x * vertices[b].y;
        result -= vertices[a].y * vertices[b].x;
    }

    return result * .5f;
}

परिणाम का संकेत (सकारात्मक या नकारात्मक) आपको बताएगा कि क्या यह दक्षिणावर्त है या एंटीलॉकवाइज़ है। आपको यह देखने की कोशिश करनी चाहिए कि यह आपके लिए किस तरह का दौर है क्योंकि यह आपके समन्वय प्रणाली पर निर्भर करता है।

यदि आकार दक्षिणावर्त है:

  • एक प्राणी जा रहा आगे आकार दौर जा रहा है दक्षिणावर्त , और
  • आकार में पीछे की ओर जाने वाला प्राणी एंटिक्लॉकवाइज होता है

यदि आकृति एंटीक्लॉक वाइज है:

  • गोल आकार में आगे की ओर जाता हुआ एक जीव एंटीलॉक वाइज जा रहा है , और
  • एक जीव जो आकार में पीछे की ओर जा रहा है, दक्षिणावर्त जा रहा है ।

0

ऐसा लगता है कि ट्रेवर ने पहले से ही इस सवाल को कवर किया है, लेकिन यहां मेरा समाधान है:

  1. उस क्षेत्र की गणना करें जिसमें आपका आकार शामिल है, जिसका अर्थ है

    area = 0
    foreach (edge in shape)
        area += edge.begin.x * edge.end.y - edge.begin.y * edge.end.x
  2. ऊपर के रूप में गणना किए गए क्षेत्र का उपयोग करके आप आसानी से बता सकते हैं कि आकार स्वयं दक्षिणावर्त है या नहीं। यदि क्षेत्र शून्य से नीचे है, तो यह केवल दक्षिणावर्त है।

  3. जाँच करें कि क्या ऑब्जेक्ट (एस) उसी तरह आगे बढ़ रहे हैं जैसे कि अनुलंब क्रम हैं या विपरीत दिशा में हैं।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.