2009-09-17 8 views
5

मेरे पास 3 डी मॉडलिंग सॉफ्टवेयर में विंडो सतहों के लिए सामान्य वैक्टरों का एक गुच्छा है। XY-विमान का अनुमान, मुझे पता है कि किस दिशा में वे सामना कर रहे हैं, 8 कम्पास का अनुवाद करना चाहते हैं निर्देशांक (उत्तर, पूर्वोत्तर, पूर्व, दक्षिण पूर्व, दक्षिण, दक्षिण-पश्चिम, पश्चिम और उत्तर-पश्चिम)।एक कंपास (एन, एनई, ई, एसई, एस, एसडब्ल्यू, डब्ल्यू, एनडब्ल्यू) में एक दिशात्मक (2 डी) वेक्टर "स्नैप" कैसे करें?

वैक्टर इस तरह काम करते हैं:

  • एक्स अक्ष पूर्व-पश्चिम का प्रतिनिधित्व करता है
  • y अक्ष उत्तर-दक्षिण
  • इस प्रकार (उत्तर सकारात्मक होने के साथ) का प्रतिनिधित्व करता है (पूर्व सकारात्मक होने के साथ)
    • (0, 1) == उत्तर
    • (1, 0) == पूर्व
    • (0, -1) == दक्षिण
    • (-1,0) पश्चिम

== एक सदिश को देखते हुए (एक्स, वाई) मैं 8 कम्पास निर्देशांक के निकटतम रहा हूँ। इस सुंदर तरीके से यह कैसे करें इस पर कोई विचार? 90 डिग्री की एक बहु के लिए यह "भगवान" के लिए या कुछ गणित:

+0

इस तरीके से टैग करने के तरीके पर कोई विचार? नि: शुल्क महसूस करें ... –

+1

नहीं, मेरे उत्तर में (1, 0) पूर्व है और यह घड़ी की दिशा में जा रहा है, क्योंकि मैं यहां गणितीय रूप से चीजें कर रहा हूं। यह नेविगेशन (0 = उत्तर, दक्षिणावर्त) में कोणों के मानक उपयोग के साथ बाधाओं पर है। आप इसे +8 पर उचित ऑफसेट जोड़कर और एटान 2 के सामने एक का उपयोग कर अनुकूलित कर सकते हैं। – starblue

+0

स्टारब्लू को इंगित करने के लिए धन्यवाद, मैं अपने स्केच के साथ खुद को भ्रमित कर रहा हूं - आपका उत्तर स्पॉट पर है! –

उत्तर

7

यह जावा में काम करता है, एक मूल्य के 0 ... 7 कंप्यूटिंग आठ दिशाओं के लिए: कम्पास के लिए

import static java.lang.Math.*;  

int compass = (((int) round(atan2(y, x)/(2 * PI/8))) + 8) % 8; 

परिणाम नक्शे इस प्रकार है:

0 => E 
1 => NE 
2 => N 
3 => NW 
4 => W 
5 => SW 
6 => S 
7 => SE 
6

मैं शायद सिर्फ शीर्षक कोण यह पता लगाने की atan2() के लिए एक कॉल करना होगा ("विचलन"), और फिर या तो if के अनुक्रम का उपयोग करें।

+0

धन्यवाद, आशाजनक लग रहा है, दोपहर के भोजन के बाद इसे देखेगा! –

4

एक ऐसा करने की जरूरत एटान समारोह

यदि आप करते हैं: y/x आपको लाइन की ढलान मिल जाएगी। आपको प्राप्त होने वाली संख्या के आधार पर आप कोण/ऑक्टेटेंट निर्धारित कर सकते हैं। => 90 डिग्री (उत्तर)

  • 2.4> (y/एक्स)> 0.4 - - => 45 डिग्री

    सकारात्मक एक्स के (एक्स> 0)

    • (y/एक्स)> 2.4 के लिए

      (उत्तर पश्चिम)

    • 0.4> (y/एक्स)> -0.4 - => 0 डिग्री (पश्चिम)
    • -0.4> (y/एक्स)> -2.4 - => -45 डिग्री (दक्षिण पश्चिम)
    • -2।4> (y/x) - => 90 डिग्री (दक्षिण)

    और नकारात्मक एक्स के

    और अंत के लिए एक समान सूची अपवाद मामलों:

    • (एक्स == 0 & & y> 0) - => -90 डिग्री (दक्षिण)
    • (एक्स == 0 & & y < 0) - => 90 डिग्री (दक्षिण)

    परिशिष्ट: मैं केवल इस विधि की रिपोर्ट करता हूं जब एटान की गणना नहीं होती है (उदाहरण के लिए एम्बेडेड सिस्टम पर))

    मुझे थोड़ा खोदना पड़ा। यहां एक अत्यधिक अनुकूलित दिनचर्या है जिसका उपयोग मैं करता हूं (मोबाइल गेम में उपयोग किया जाता है)।

    इनपुट: x1, y1 = वेक्टर x2, y2 = वेक्टर के अंतिम बिंदु का startpoint निर्गम (0-7) = 0 = उत्तर, 1 = उत्तर पश्चिम, 2 = पश्चिम, ... आदि

    int CalcDir(int x1, int y1, int x2, int y2) 
    { 
         int dx = x2 - x1, dy = y2 - y1; 
         int adx = (dx<0)?-dx:dx, ady = (dy<0)?-dy:dy, r; 
         r=(dy>0?4:0)+(dx>0?2:0)+(adx>ady?1:0); 
         r=(int []){2,3,1,0,5,4,6,7}[r]; 
         return r; 
    } 
    
    void CalcDirTest(){ 
         int t = CalcDir(0, 0, 10, 1); 
         printf("t = %d",t); 
         t = CalcDir(0, 0, 9, 10); 
         printf("t = %d",t); 
         t = CalcDir(0, 0, -1, 10); 
         printf("t = %d",t); 
         t = CalcDir(0, 0, -10, 9); 
         printf("t = %d",t); 
         t = CalcDir(0, 0, -10, -1); 
         printf("t = %d",t); 
         t = CalcDir(0, 0, -9, -10); 
         printf("t = %d",t); 
         t = CalcDir(0, 0, 1, -10); 
         printf("t = %d",t); 
         t = CalcDir(0, 0, 10, -9); 
         printf("t = %d",t); 
    } 
    

    यह निम्न उत्पादन में परिणाम होगा:

    t = 7 
    t = 6 
    t = 5 
    t = 4 
    t = 3 
    t = 2 
    t = 1 
    t = 0 
    

    (परीक्षण के लिए वैक्टर देखो अजीब तरह से चुना हो सकता है, लेकिन मैं उन्हें फेरबदल सब थोड़ा स्पष्ट रूप से एक ओक्टांट में और सही सीमा पर नहीं होने के लिए)

  • +0

    मुझे नहीं लगता कि अंतिम अनुकूलित दिनचर्या कैसे काम कर सकती है क्योंकि आर मान आसानी से अज्ञात सरणी आकार से अधिक हो सकता है। – GregM

    +0

    अच्छी तरह से देखा गया। बग फिक्स्ड – Toad

    3

    यह एटान 2 का उपयोग नहीं करता है, और प्रति कॉल 4 सबसे खराब और 2 उत्पादों पर करता है। 4 आंतरिक ब्लॉक में एक्स से वाई की तुलना करना (मैंने इसे केवल पहले ब्लॉक में संपादित किया है), इसे कम 4 तुलना और 1 उत्पाद प्रति कॉल तक घटाया जा सकता है।

    int compass(double x,double y) 
    { 
        double t = 0.392699082; // tan(M_PI/8.0); 
    
        if (x>=0) 
        { 
        if (y>=0) 
        { 
         if (x>y) { if (y<t*x) return E_COMPASS; } 
         else { if (x<t*y) return N_COMPASS; } 
         return NE_COMPASS; 
        } 
        else 
        { 
         if (-y<t*x) return E_COMPASS; 
         if (x<-t*y) return S_COMPASS; 
         return SE_COMPASS; 
        } 
        } 
        else 
        { 
        if (y>=0) 
        { 
         if (y<-t*x) return W_COMPASS; 
         if (-x<t*y) return N_COMPASS; 
         return NW_COMPASS; 
        } 
        else 
        { 
         if (-y<-t*x) return W_COMPASS; 
         if (-x<-t*y) return S_COMPASS; 
         return SW_COMPASS; 
        } 
        } 
        return E_COMPASS; 
    } 
    
    संबंधित मुद्दे