본문 바로가기
Programming/Algorithm

[Alogrithm] 지구에서 두 점 사이의 거리 구하기

by SpiralMoon 2020. 8. 25.
반응형

지구에서 두 점 사이의 거리 구하기

지구에서 두 점 사이의 거리를 구하는 방법을 알아보자.

서울에서 뉴욕까지의 최단거리. 11065km

이 글은 원본인 Calculate distance, bearing and more between Latitude/Longitude pointsDistance 항목을 번역한 글이다.


시리즈

2020/09/07 - [Programming/Algorithm] - [Algorithm] 지구에서 두 점 사이의 방위각 구하기

2020/09/15 - [Programming/Algorithm] - [Algorithm] 지구에서 두 점 사이의 중간지점 구하기


사전 지식

라디안

 

라디안 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 라디안단위의 종류SI 유도 단위측정 대상각기호rad 또는 c 단위무한분량단위 환산 1 rad ▼동등 환산값    밀리라디안   1,000 밀리라디안   바퀴   1/2π

ko.wikipedia.org

우리가 사용하고 있는 지도의 문제점

 

우리가 사용하고 있는 지도의 문제점

※ 이 글은 VISUAL CAPITALIST에 기고된 「The Ploblem With Our Maps」를 번역한 글입니다. 지도는 우리가 세계를 이해하게 해준다. 또한 점점 더 서로 밀접하게 연결된 세계 경제에서 이런 지리적 지식은 ��

ppss.kr


하버사인 공식을 이용하여 최단거리 구하기

하버사인 공식구에서 두 점 사이의 거리를 구할 때 쓰이는 공식이다.

즉, 지구 표면에서 가장 짧은 거리인 점들 사이의 합을 얻을 수 있다.

(지구가 완벽한 구는 아니라서 아주 조금의 오차가 있긴 하다.)

 

아래 예시들은 모두 자바스크립트로 작성되었으나, 대부분 언어들의 Math 모듈을 이용한 식과 다르지 않다.

haversine formula

a = sin²(Δφ / 2) + cos φ₁ ⋅ cos φ₂ ⋅ sin²(Δλ / 2)
c = 2 ⋅ atan2(√a, √(1−a))
d = R ⋅ c

φ는 latitude(위도), λ는 longitude(경도), R은 지구의 반지름(6,371km)이다.

source code

// 출발지 (서울)
const lat1 = 37.56654;
const lon1 = 126.97796;

// 목적지 (뉴욕)
const lat2 = 40.71295;
const lon2 = -74.00607;

const R = 6371e3; // 지구의 반지름 (meter)

// 좌표를 라디안 단위로 변환
const φ₁ = lat1 * Math.PI / 180;
const φ₂ = lat2 * Math.PI / 180;
const Δφ = (lat2 - lat1) * Math.PI / 180;
const Δλ = (lon2 - lon1) * Math.PI / 180;

const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
		  Math.cos(φ₁) * Math.cos(φ₂) *
          Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

const d = R * c; // meter

// d = 11052555.850341197

 

하버사인 공식은 작은 거리에서도 수치 계산을 위한 양호한 상태를 유지하므로, 구면 코사인 법칙에 기초한 계산과는 다르다.

a는 두 점 사이의 현 길이 절반의 제곱이며, c는 각거리를 라디안으로 표시한 것이다.

 

만약 atan2 함수를 사용할 수 없으면, c를 2 ⋅ asin( min(1, √a) )로 계산할 수도 있다.

(대신, 반올림 오류에 대한 처리를 해주어야 함)

 

계산속도는 대략 중급 i5 CPU를 사용하는 PC에서 2 ~ 5 마이크로초가 소요된다. 따라서 초당 20만~50만까지 연산할 수 있다.


Spheical Law of Cosines (구면 코사인 법칙)

자바스크립트나 대부분의 최신 컴퓨터 및 언어에서는 'IEEE 754'를 지원하기 때문에 64bit의 부동 소수점 수를 사용하며, 소수점 15자리까지 정밀도를 제공한다.

 

추측에 의하면, 이 정밀도로 코사인 공식(cos c = cos a cos b + sin a sin b cos C)의 간단한 구면 법칙은 지구 표면에서 몇 미터 만큼 작은 거리까지 잘 보정된 결과를 제공할 것이다.

다만, 아주 작은 거리의 경우 정방형 근사가 더 적합 할 수 있다.

 

이것은 코사인의 간단한 법칙을 많은 측지 목적을 위해, 하버사인 공식에 대한 합리적인 대안이다.

 

law of cosines

d = acos(sin φ₁ ⋅ sin φ₂ + cos φ₁ ⋅ cos φ₂ ⋅ cos Δλ) ⋅ R

source code

 

// 출발지 (서울)
const lat1 = 37.56654;
const lon1 = 126.97796;

// 목적지 (뉴욕)
const lat2 = 40.71295;
const lon2 = -74.00607;

// φ, λ을 라디안으로 변환
const φ₁ = lat1 * Math.PI / 180
const φ₂ = lat2 * Math.PI / 180;
const Δλ = (lon2 - lon1) * Math.PI / 180;

// 지구의 반지름 (meter)
const R = 6371e3;

const d = Math.acos(Math.sin(φ₁) * Math.sin(φ₂) +
                    Math.cos(φ₁) * Math.cos(φ₂) * Math.cos(Δλ)
          ) * R;
          
// d = 11052555.850341197

 

하버사인 공식보단 간단하지만 계산속도가 약간 느릴 수 있다.


Equirectangular approximation (정방형 근사)

만약 계산 성능이 좀 더 높고 정확도가 덜 중요한 상황이라면, 짧은 거리에 한하여(거리가 길 수록 오차가 심함) 피타고라스의 정리를 정방형 투영에 사용할 수 있다.

formula

x = Δλ ⋅ cos φ𝚖
y = Δφ
d = R ⋅ √x² + y²

source code

const x = (λ₂ - λ₁) * Math.cos((φ₁ + φ₂) / 2);
const y = (φ₂ - φ₁);
const d = Math.sqrt(x * x + y * y) * R;

 

이 방법은 단지 한 번의 삼각함수(cos)와 한 번의 제곱근만으로 계산하는 방법이다.

하버사인 공식이 일곱 번의 삼각함수와 두 번의 제곱근을 사용하는 것과 차이가 있다.

 

정확도는 다소 복잡하며, 자오선을 따라 오류가 없다. 그렇지 않으면 거리, 방위, 위도에 따라 달라지지만 사소한 수준이다.


원본

 

Calculate distance and bearing between two Latitude/Longitude points using haversine formula in JavaScript

This page presents a variety of calculations for lati­tude/longi­tude points, with the formulas and code fragments for implementing them. All these formulas are for calculations on the basis of a spherical earth (ignoring ellipsoidal effects) – which i

www.movable-type.co.uk

 

반응형

댓글