Usiłuję opracować „formułę” w celu poprawienia wartości w całym języku.
Korzystam z ulotki vue, ale kiedy patrzysz poza „pierwszym” światem, dostajesz duże liczby. Ponad +180 lub poniżej -180.
Na przykład: kiedy przesuję się do Ameryki w prawo (kierunek wschodni), otrzymam wartość 215. W mojej głowie po prostu poprawiłbym to 215-360=-145
To samo dotyczy przesuwania się na wschodnią Rosję w lewo (kierunek zachodni) i otrzymuję na przykład -222. Teraz muszę obliczyć-222+360=138
Ponieważ jednak świat jest nieokreślony, użytkownik może przesuwać się do ósmego świata i musiałem dostosować wartości.
Czy można obliczyć odpowiednią długość geograficzną? (a kolejnym wymaganiem jest, gdy użytkownik jest w pierwszym świecie, 24 lng powinno nadal wynosić 24 lng.
źródło
while (Math.abs(lon) > 180) { lon -= Math.sign(lon) * 360 }
ale nie udzielam jej jako odpowiedzi, ponieważ twoja wersja faktycznie pasuje do wyjaśnienia, podczas gdy moja wersja jest tylko optymalizacją, która prawdopodobnie nie robi żadnej różnicy. Zachowuję to jako komentarz tylko jako przypomnienie, że rzeczy można robić na wiele sposobów, niektóre bardziej zoptymalizowane niż inne.lon %= 180
?Odpowiedź, która pozwala uniknąć poleceń warunkowych i wywołań funkcji:
Napisałem szybki znak microbench na https://jsperf.com/longitude-normalization, a kod warunkowy wydaje się być szybszy (w Chrome na moim komputerze) dla „rozsądnych” zakresów wartości wejściowych. Ogólnie rzecz biorąc, prawdopodobnie nie powinieneś martwić się z góry wydajnością w takich małych obliczeniach, zwiększając czytelność i spójność z resztą bazy kodu.
Prawdopodobnie ważniejsze w tym przypadku jest pytanie, czy Twój kod może kiedykolwiek spotkać skrajne wartości wejściowe (1e10, Infinity itp.). Jeśli tak, implementacja zapętlenia może kończyć się bardzo powolnym lub cichym zawieszeniem programu. Może się to zdarzyć w obliczeniach przeprowadzonych w pobliżu biegunów, np. Próba przesuwania wschodu lub zachodu na pewną odległość (a nie kąt) od bieguna może łatwo doprowadzić do nieskończonej długości geograficznej.
źródło
Jednowarstwowy:
Objaśnienie: Chcesz wiedzieć, co pozostanie po zignorowaniu pełnych obrotów (360 °).
Ten proces nazywa się normalizacją.
Przykład (cpp.sh)
źródło
remainder
jakomodulus
. Moduł w JS dałby [0, 360).-1 % 3
Wynosi -1, a nie 2, co byłoby konieczne, aby działał tutaj.remainder
jest świetnym rozwiązaniem C ++, ale niestety w JS nie ma funkcji / operatora, który byłby na tyle podobny, aby był użyteczny.Inna opcja: longitude = atan2 (cos (long), sin (long))
źródło
Jeśli używany język programowania obsługuje operator% (mod) na liczbach zmiennoprzecinkowych (takich jak Python i Ruby), zalecam użycie tego. W przeciwnym razie niektóre inne języki (np. C i C ++) pozwalają na użycie fmod ().
(Niezależnie od tego, którego operatora modowego używasz, upewnij się z wyprzedzeniem, że wykona on operacje modowe na liczbach zmiennoprzecinkowych i że zawsze da ci odpowiedzi nieujemne. W przeciwnym razie otrzymasz paskudną niespodziankę, gdy wielu punkty lat / lon są nieprawidłowe.)
Użyj tego w ten sposób:
Jeśli wolisz to wszystko zrobić w jednym wierszu:
Te podejścia nie mają pętli, więc znormalizują wartości długości geograficznej bez konieczności wielokrotnego dodawania lub odejmowania, bez względu na to, ile razy Twoja obserwacja krążyła wokół Ziemi.
Edytować:
Hmmm ... Właśnie zauważyłem, że JavaScript nie radzi sobie
%
z wartościami ujemnymi, tak jak myślałem.W takim przypadku wypróbuj ten jedno-liniowy:
36180
Dodajemy to 36000 + 180. 36.000 jest przeniesienie wartości ujemnej do dodatniej domenie, a 180 jest przesunięcie go tak, że gdy jest modded przez360
, to będzie w przedziale [0360) . Na- 180
część przesuwa go z powrotem do zakresu [-180,180).Oto kolejna linijka, która nie polega na wystarczającej wielkości 36 000:
longitude % 360 + 360
Część zapewni pobyty w wartości dodatniej domenie kiedy to później przez modded360
. W+ 180
części przesunięcia go na tak, że gdy później dostaje 180 odejmowana od niej (z- 180
), to będzie w pożądanym przedziale [-180,180).źródło
fmod(longitude, 360)
-> (-360,0 ... +360,0) iilongitude % 360
-> [-359 ... +359].