2010-01-25 13 views
14

इस सप्ताहांत में मैं एक एल्गोरिदम को एक साथ जोड़कर कुछ मिनट बिताता हूं जो एक शीर्षक (डिग्री में) लेता है और कार्डिनल दिशा के लिए एक स्ट्रिंग लौटाता है (मैं इसे एंड्रॉइड कंपास एप्लिकेशन I में उपयोग कर रहा हूं। एम का उपयोग कर)। क्या मैं के साथ समाप्त हो गया यह था:जावा में कार्डिनल दिशा एल्गोरिदम

private String headingToString(Float heading) 
{ 
    String strHeading = "?"; 
    Hashtable<String, Float> cardinal = new Hashtable<String, Float>(); 
    cardinal.put("North_1", new Float(0)); 
    cardinal.put("Northeast", new Float(45)); 
    cardinal.put("East", new Float(90)); 
    cardinal.put("Southeast", new Float(135)); 
    cardinal.put("South", new Float(180)); 
    cardinal.put("Southwest", new Float(225)); 
    cardinal.put("West", new Float(270)); 
    cardinal.put("Northwest", new Float(315)); 
    cardinal.put("North_2", new Float(360)); 

    for (String key: cardinal.keySet()) 
    { 
     Float value = cardinal.get(key); 
     if (Math.abs(heading - value) < 30) 
     { 
      strHeading = key; 
      if (key.contains("North_")) 
      { 
       strHeading = "North"; 
      } 
      break; 
     } 
    } 
    return strHeading; 
} 

मेरा प्रश्न है, इस ऐसा करने का सबसे अच्छा तरीका है? यह कई बार पहले किया जाना चाहिए हालांकि मैंने अभी तक वेब पर उदाहरणों की खोज नहीं की है। क्या किसी अन्य लोगों ने यह कोशिश की है और एक स्वच्छ समाधान मिला है? Reverand के थिलो की, SHINJIN की और Chrstoffer की प्रतिक्रियाओं के लिए

संपादित करें:

समाधान

public static String headingToString2(double x) 
{ 
    String directions[] = {"N", "NE", "E", "SE", "S", "SW", "W", "NW", "N"}; 
    return directions[ (int)Math.round(( ((double)x % 360)/45)) ]; 
} 

उत्तर

27

ज्यादातर मामलों में यह ठीक है, हालांकि इसे अनुकूलित करने और (आईएमओ) क्लीनर बनाने के लिए, आप क्या कर सकते हैं, मानचित्र में उपयोग किए जाने वाले इनपुट शीर्षक से संबंधित एक फ़ंक्शन ढूंढना है।

उदाहरण के लिए: (मैं बहुत यकीन है कि यह सही है, लेकिन आप इसे जांचना चाहेंगे)

45* (int)Math.round(( ((double)x % 360)/45)) 

क्या करता है पहला है x % 360 सुनिश्चित करती है शीर्षक मान्य श्रेणी में है। तो

45 * round(.../45) 

पाता है 45

के निकटतम कई अब अपने नक्शे को बदलने

HashMap<Integer, String> map = new HashMap<Integer, String>() 
    map.put(0, "North") 
    map.put(45, "Northeast") 
    etc... 

तो, अब अपने एल्गोरिथ्म बल्कि मानचित्र के माध्यम से पुनरावृत्ति की तुलना में एक तेजी से mathemtical गणना हो जाता है हो सकता है। इसके अलावा, आपको यहां हैशटेबल की आवश्यकता नहीं है क्योंकि यह समेकन के लिए संरचनाएं प्रदान करता है (यदि मुझे सही याद है) और आपके मामले में यह वास्तव में प्रदर्शन में कमी का कारण बनता है।

एक बार फिर, प्रदर्शन हिट आपकी आवश्यकताओं के लिए पूरी तरह से नगण्य हो सकती है। थिलो की और Shinjin के सुझावों के लिए

संपादित करें:

बजाय 45 से गुणा करने के लिए, बस समीकरण है, जो आप 0-7 के लिए मान देता है के बाकी रखने के लिए, और अपने तार की एक सरणी हैं।

String directions[] = {"N", "NE", "E", "SE", "S", "SW", "W", "NW"} 
return directions[ (int)Math.round(( ((double)x % 360)/45)) % 8 ] 

और आपको अपनी समस्या दो पंक्तियों में हल हो गई है।

एक नोट: मॉड्यूलस नकारात्मक संख्याओं के लिए सही तरीके से काम नहीं करेगा। यदि हमारा इनपुट शीर्षक नकारात्मक है, तो आपको इसे पहले सकारात्मक बनाना होगा।

+1

+1:

यहाँ एक समाधान 22.5 डिग्री अंतराल, आप हवा दिशाओं के लिए देख सकते हैं इस तरह के रूप का उपयोग करता है है। बहुत अच्छा। इसे एक कदम आगे लेते हुए, फ़ंक्शन में एक और छोटा रूपांतरण जोड़ें और वह केवल स्ट्रिंग्स की सरणी में एक अनुक्रमणिका प्राप्त कर सकता है: 'स्ट्रिंग [] दिशानिर्देश = {"एन", "एनई", "ई" ...} ' – Thilo

+1

यदि आप गुणा को 45 से छोड़ देते हैं, तो आप हैश मैप के बजाय एक साधारण सरणी का उपयोग कर सकते हैं। – shinjin

+1

आपको उस सरणी में एक अतिरिक्त "एन" की आवश्यकता है। शीर्षलेख 337.5 और ऊपर 8 तक होगा। –

0

आप शायद North_1 और North_2 से बचने के लिए सामने 15 डिग्री जोड़ सकते हैं।

-1
जावा में

:

String _directions[] = {"N", "NE", "E", "SE", "S", "SW", "W", "NW"}; 

public String getHeading(int hea) { 
    return _directions[(int)Math.floor((hea % 360)/45)]; 
} 

"जावा" मामले यू एक कक्षा बनाने की आवश्यकता चाहिए।

जावास्क्रिप्ट में

:

var _directions = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"]; 

function getDirection (hea) { 
    return _directions[Math.floor((hea % 360)/45)]; 
}; 
0

पिछले उदाहरण, सही नहीं हैं यहाँ जावास्क्रिप्ट में एक और अधिक सटीक उपाय है।

function getCardinalDirection(input) { 
    var directions = ["N", "NE", "E", "SE", "S", "SW", "W", "NW", "N"]; 
    var index = Math.floor(((input-22.5)%360)/45); 
    return directions[index+1]; 
} 
7

जवाब यहां के अधिकांश बंद 22.5 डिग्री तक उनके 45 डिग्री के अंतराल के लिए कर रहे हैं, और जैसे नक्शा 0-45 एन के रूप में, [337.5-360], [0-22.5] के बजाय एन। आपको इसके लिए सही करने के लिए गणित करने से पहले ऑफ़सेट करने की आवश्यकता है।

private String formatBearing(double bearing) { 
    if (bearing < 0 && bearing > -180) { 
     // Normalize to [0,360] 
     bearing = 360.0 + bearing; 
    } 
    if (bearing > 360 || bearing < -180) { 
     return "Unknown"; 
    } 

    String directions[] = { 
     "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", 
     "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW", 
     "N"}; 
    String cardinal = directions[(int) Math.floor(((bearing + 11.25) % 360)/22.5)]; 
    return cardinal + " (" + formatBearing.format(bearing) + " deg)"; 
    } 
+2

क्या यह सामान्य है कि आपके निर्देशों की सरणी में एन दो बार है? – Pak

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