2012-11-13 13 views
5

मेरे पास युगल है जो अक्षांश और अक्षांश का प्रतिनिधित्व करता है।
मैं आसानी से देशांतर (-180.0 के लिए, निम्न कार्य के साथ सीमित कर सकते हैं 180.0]अक्षांश और देशांतर मानों को सीमित करने के लिए मॉड्यूलस

double limitLon(double lon) 
{ 
    return fmod(lon - 180.0, 360.0) + 180.0; 
} 

यह काम करता है क्योंकि एक छोर अनन्य है और अन्य शामिल है। Fmod 0 नहीं बल्कि -360.0 भी शामिल है।

किसी अक्षांश के लिए एक सुंदर विधि के बारे में सोच सकते हैं?
आवश्यक अंतराल [-90.0, 90.0] है। एक बंद फ़ॉर्म समाधान सबसे अच्छा होगा, यानी कोई पाश। मुझे लगता है कि fmod() शायद एक गैर है स्टार्टर क्योंकि दोनों सिरों अब समावेशी हैं।

संपादित करें: जैसा कि बताया गया था, कोई भी 91 डिग्री अक्षांश पर नहीं जा सकता है। तकनीकी रूप से 91 को 89.0 पर नक्शा करना चाहिए। ओह लड़का, जो चीजों को बदलता है।

+1

आप 91 से अनुवाद करने की क्या अपेक्षा करेंगे? यदि आप एक डिग्री से ध्रुव पर जाते हैं तो आप वापस 89-89 पर वापस आ जाएंगे। –

+0

उत्कृष्ट बिंदु। अक्षांश लपेटते नहीं हैं क्योंकि आप वास्तव में ध्रुव को "पार" नहीं कर सकते हैं। हालांकि, अंतरराष्ट्रीय तिथि रेखा पार कर सकते हैं। – William

+1

क्या आपका मतलब एफएमओडी (लॉन + 180.0, 360.0) - 180.0; ? –

उत्तर

2

sin और व्यस्त कार्यों का उपयोग करने के बारे में कैसे?

asin(sin((lat/180.0)*3.14159265)) * (180.0/3.14159265); 
+0

'asin' रेडियंस लौटाता है, 'पाप' रेडियंस की अपेक्षा करता है। – lhf

+0

कन्वर्ट करने के लिए काफी आसान है। – William

+0

यह निश्चित रूप से सही ट्रैक है। त्रिकोणमिति कार्य दोनों सिरों पर समावेशी होते हैं। – William

4

पाप और आर्केसिन का उपयोग करने से ऐसा करने के लिए एक बहुत अधिक कुशल तरीका है। सबसे महंगा ऑपरेशन एक एकल विभाजन है। अवलोकन कि आवश्यक अंतराल बंद है कुंजी है।

  • 360 से विभाजित करें और शेष को लें। यह अंतराल [0, 360) में एक संख्या उत्पन्न करता है, जो देखा गया है, जो आधा खुला है।

  • आधे में अंतराल को मोड़ो। यदि शेष है> = 180, इसे 360 से घटाएं। यह अंतराल [180, 360) अंतराल (0, 180] पर अंतराल को मानचित्र करता है। नीचे के आधे भाग के साथ इस अंतराल का संघ बंद अंतराल [0, 180] है।

  • परिणाम से 90 घटाएं। वांछित के रूप में यह अंतराल [-90, 90] है।

यह, वास्तव में arcsin(sin(x)) के रूप में ठीक उसी समारोह है, है, लेकिन खर्च या संख्यात्मक स्थिरता के साथ किसी भी मुद्दे के बिना।

+0

यह काम नहीं करता है या कुछ चरणों को याद कर रहा है। बस 5 डिग्री का परीक्षण करें और तर्क प्रवाह के बाद, इसका परिणाम "घटाना 90" चरण के बाद 5 डिग्री नहीं होता है। स्पष्टीकरण के लिए कोड पोस्ट करें। – krisdestruction

1

कोई भी उत्तर प्रदान नहीं किया गया (डी स्टेनली, एएच 9) काम करता है ... हालांकि eh9 के लिए मैं कुछ गलत व्याख्या कर सकता हूं। उन्हें कई मानों के साथ आज़माएं।

उचित उत्तर दुर्भाग्य से महंगा हैं। माइक्रोसॉफ्ट रिसर्च से निम्नलिखित देखें: http://research.microsoft.com/en-us/projects/wraplatitudelongitude/

वहाँ से, उत्तर दिए गए हैं:
latitude_new = atan(sin(latitude)/fabs(cos(latitude))) - चारों ओर क्योंकि (अक्षांश) निरपेक्ष मूल्य ध्यान दें

longitude_new = atan2(sin(latitude),cos(latitude)) 

ध्यान दें कि सी में आप atan2f (नाव vs डबल) का उपयोग कर सकते हैं। इसके अलावा, सभी ट्रिग फ़ंक्शन रेडियंस लेते हैं।

+0

मैं अभी स्रोत से गायब होने वाले कोष्ठक को बंद करने के लिए वापस आया ... धन्यवाद @ मैक्यन (और कोड डिस्प्ले फिक्स के लिए)। – AdamC

+0

यह लिंक अब मृत है = ( – superbeck

4

ट्रिग फ़ंक्शंस का उपयोग sin()/cos() समय पर महंगा है और सटीकता का नुकसान प्रस्तुत करता है। remainder() फ़ंक्शन का उपयोग करने के लिए बहुत बेहतर है। ध्यान दें कि परिणाम x के समान संकेत है और यदि सक्षम हो तो y की परिमाण से कम परिमाण है।

ओपी सही रास्ते पर था! नीचे दिया गया समाधान -180 और + 180.0 के किनारे मानों के अनुसार समायोजित करना आसान है।

#include <math.h> 

// Reduce to (-180.0, 180.0] 
double Limit_Longitude(double longitude_degrees) { 
    // A good implementation of `fmod()` will introduce _no_ loss of precision. 
    // -360.0 <= longitude_reduced <=- 360.0 
    double longitude_reduced = fmod(longitude_degrees, 360.0); 

    if (longitude_reduced > 180.0) { 
    longitude_reduced -= 360.0; 
    } else if (longitude_reduced <= -180.0) { 
    longitude_reduced += 360.0; 
    } 
    return longitude_reduced; 
} 

[-90 +90 करने के लिए] के लिए अक्षांश सीमित जटिल काम के रूप में 91 डिग्री की एक अक्षांश उत्तरी ध्रुव पर जा रहा है लेकिन देशांतर +/- 180 डिग्री स्विचन जाता है। देशांतर परिशुद्धता को संरक्षित करने के लिए 180 से 0 डिग्री समायोजित करें।

void Limit_Latitude_Longitude(double *latitude_degrees, double *longitude_degrees) { 
    *latitude_degrees = Limit_Longitude(*latitude_degrees); 
    int flip = 0; 
    if (*latitude_degrees > 90.0) { 
    *latitude_degrees = 180.0 - *latitude_degrees; 
    flip = 1; 
    } else if (*latitude_degrees < -90.0) { 
    *latitude_degrees = -180.0 - *latitude_degrees; 
    flip = 1; 
    } 
    if (flip) { 
    *longitude_degrees += *longitude_degrees > 0 ? -180.0 : 180.0; 
    } 
    *longitude_degrees = Limit_Longitude(*longitude_degrees); 
} 
संबंधित मुद्दे