| 180 | 이상일 때 정확한 경도 계산하기?


11

위도 값을 수정하기 위해 "수식"을 개발하려고합니다.

나는 vue-leaflet을 사용하고 있지만 "첫 번째"세계 밖으로 패닝하면 큰 숫자를 얻습니다. +180 이상 또는 -180 미만

예를 들어, 내가 오른쪽 (동쪽 방향)으로 미국으로 이동하면 lng 215가됩니다. 내 마음으로는 215-360=-145

내가 동쪽 러시아로 왼쪽 (서쪽 방향)으로 이동하고 예를 들어 -222를 얻는 것과 같습니다. 이제 계산해야합니다-222+360=138

그러나 세계는 무기한이므로 사용자는 8 세계로 이동할 수 있으며 값을 조정해야했습니다.

올바른 경도를 계산할 수 있습니까? (또 다른 요구 사항은 사용자가 첫 번째 세계에있을 때 24 lng는 여전히 24 lng이어야합니다.

답변:


16

360이 -180-180 범위에이를 때까지 값에 360을 반복적으로 더하거나 뺄 필요가 있습니다. 따라서 일반적으로 다음과 같은 루프 쌍이 있습니다.

lon = -187;
while(lon < -180){
  lon +=360;
}
while (lon > 180){
  lon -= 360;
}

길을 잘못 표지판? 첫 번째 경우 론 + = 360이어야합니다.
JimT

4
while (Math.abs(lon) > 180) { lon -= Math.sign(lon) * 360 }귀하의 버전이 실제로 설명과 일치하기 때문에 하나의 루프로만 답변을 제공 할 수는 없지만 내 버전은 차이가 없을 수있는 최적화 일뿐입니다. 나는 여러 가지 방법으로 수행 할 수 있으며 일부는 다른 방식보다 더 최적화 될 수 있음을 상기시키기 위해 주석으로 만 사용합니다.
Andrei

2
루프 당 2 개의 함수 호출을 사용하므로 루프 중 하나만 사용한다고 생각하지 않으며 루프 중 하나만 실행됩니다. 아마도이 예에서는 차이가 없지만 저의 편견입니다
Ian Turton

함수처럼 보이지만 JavaScript의 수학 함수는 자세한 기호가있는 연산자와 비슷해야합니다. 이런 의미에서 우리는 +-와 심지어 <를 함수로 볼 수도 있습니다. 편집 : 실제로 작동하지 않는 해결책이 있습니다.
Andrei

2
당신은 할 수 lon %= 180없습니까?
기금 모니카의 소송

15

조건부와 함수 호출을 피하는 답변 :

longitude = (longitude % 360 + 540) % 360 - 180

https://jsperf.com/longitude-normalisation 에서 빠른 마이크로 벤치 마크를 작성 했으며 조건부 코드는 (합리적인) 입력 값 범위에 대해 (내 컴퓨터의 Chrome에서) 더 빠릅니다. 일반적으로 이와 같은 작은 계산의 성능에 대해 미리 걱정하지 않아도되므로 가독성 및 나머지 코드베이스와의 일관성에 더 많은 가중치를 부여 할 수 있습니다.

이 경우 아마도 더 중요한 것은 코드가 극단적 인 입력 값 (1e10, Infinity 등)을 가로 질러 올 수 있는지에 대한 문제입니다. 그렇다면 루핑 구현으로 인해 프로그램이 실제로 느리게 또는 자동으로 중단 될 수 있습니다. 극 근처에서 수행 된 계산에서 발생할 수 있습니다. 예를 들어 극에서 일정한 거리 (각도가 아닌)만큼 동쪽 또는 서쪽으로 이동 하면 무한 경도가 쉽게 나타날 수 있습니다 .


1
흥미 롭군 FP 나누기와 조건부 jmp를 경쟁합시다. 흠.
Joshua

1
@Joshua 조건부 점프를 사용할 수 없습니다. 루프라는 여러 조건부 점프 를 사용해야 합니다. (또한 루프에는 부동 소수점 추가가 포함되어 있으며, 무료는 아닙니다.) 루프에 필요한 반복 횟수는 입력에 따라 다릅니다. 따라서 성능을 확인하려면 데이터에 대해 알아야합니다. 대다수가 원하는 범위에 가깝고 반복이 거의 필요하지 않으면 추가 루프가 더 빠를 수 있지만 비꼬는 말이 제시하는 것처럼 명확하지 않습니다.
jpmc26

1
@ jpmc26 :이 경우 루프를 두 번 이상 돌 것으로 기대하는 것은 어리 석습니다.
Joshua

1
풍자는 없었습니다. 나는 실제로 어떤 방법으로 떨어질지 모른다.
Joshua

1
@Joshua yep, 나는 확실하지 않았다 :). 나는 성능에 대한 답변 (루프 코드의 잠재적 실패 케이스)에 더 많은 추가
조 리 - Moyet에게

5

짧막 한 농담:

normalized = remainder(longitude, 360);

설명 : 전체 회전 (360 °)을 무시한 후 남은 내용을 알고 싶습니다.

이 과정을 정규화라고합니다.

예 (cpp.sh)


1
이것이 Shadrix가 요청한대로 [-180, 180]이 아닌 [0, 360) 값이 아닙니까?
모자와 사람

이 예제를 확인 @TheGuywithTheHat : cpp.sh/7uy2v
기반

아, 이것이 C ++인지 몰랐습니다. Shadrix의 JavaScript 컨텍스트에서 나는로 해석 remainder했다 modulus. JS의 계수는 [0, 360)이됩니다.
모자와 사람

1
나는 그것이 효과가 있다고 생각하지 않습니다. 360 iff result> 180을 빼야합니다. JavaScript로 방금 깨달은 또 다른 문제는 모듈로가 0에서 대칭 적입니다. 예를 들어 -1 % 3여기서 작동하는 데 필요한 2가 아니라 -1입니다. remainder는 훌륭한 C ++ 솔루션이지만 불행히도 JS에는 유용 ​​할만 큼 비슷한 함수 / 연산자가 없습니다.
모자와 사람

0

다른 옵션 : 경도 = atan2 (cos (long), sin (long))


1
이것은 좋은 생각처럼 보이지 않습니다. 이해하기가 어렵고 계산 비용이 많이 들고 반올림 오류가 발생할 수 있습니다.
David Richerby

0

사용중인 프로그래밍 언어가 부동 소수점 숫자 (Python 및 Ruby와 같은)에서 % (mod) 연산자를 지원하는 경우 해당 언어를 사용하는 것이 좋습니다. 그렇지 않으면 C 및 C ++와 같은 일부 다른 언어에서는 fmod ()를 사용할 수 있습니다.

(mod 연산자를 사용하는 경우 부동 소수점 숫자에 대해 mod 연산을 수행하고 항상 음수가 아닌 응답을 제공하는지 미리 확인하십시오. 그렇지 않으면 나중에 많은 사람들이 놀랄 때 놀랄 것입니다 위도 / 경도 포인트가 올바르지 않습니다.)

다음과 같이 사용하십시오.

# Put the longitude in the range of [0,360):
longitude %= 360

# Put the longitude in the range of [-180,180):
if longitude >= 180:
    longitude -= 360

한 줄에 모든 작업을 수행하려면 다음을 수행하십시오.

# Put the longitude in the range of [-180,180):
longitude = (longitude + 180) % 360 - 180

이 방법에는 루프가 없으므로 관측치가 지구 주위를 몇 번 돌았는지에 관계없이 반복적으로 더하거나 빼지 않고도 경도 값을 정규화합니다.

편집하다:

흠 ... 방금 자바 스크립트가 %생각했던 것처럼 음수 값 을 처리하지 않는 것으로 나타났습니다 .

이 경우이 라이너 하나를 사용해보십시오.

longitude = (longitude + 36180) % 360 - 180

36180우리는 추가하는 36,000 + 180 36,000 포지티브 도메인으로 음의 값으로 이동하는 것, 그리고 180 이상이므로 의해 modded하게 될 때를 이동하는 360범위에서, 그것이 될 것이다 [0,360) . - 180부분 시프트 그것은 [-180,180)의 범위로 다시.

여기에 또 하나의 라이너가 있는데, 36,000이 충분히 크지 않다는 것입니다.

longitude = (longitude % 360 + 360 + 180) % 360 - 180

longitude % 360 + 360가 나중에에 의해 modded하게 된 때 부분은 긍정적 도메인의 가치 숙박을 보장합니다 360. + 180는 나중에 (와 감산 180 오면 일부 변화는 그 위에 그래서 - 180)는 [-180,180)의 바람직한 범위 내에있을 것이다.


1
참고 : C, C ++ fmod(longitude, 360)-> (-360.0 ... +360.0) 및 ilongitude % 360-> [-359 ... +359].
chux-복원 Monica Monica

@chux-나는 그것에 대해 몰랐기 때문에 방금 테스트했으며 올바른 것으로 보입니다. 지적 해 주셔서 감사합니다.
JL
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.