2016-08-25 13 views
0

게임의 경우지도의 항목이 플레이어의 범위 내에 있는지 계산해야합니다. 지도가 지구입니다. Haversine 공식을 사용하여 플레이어와 각 항목 간의 거리를 계산합니다. 그러나 프로파일 링을 한 결과, 모든 sin/cos 계산이 너무 느려서 smoth 게임 플레이를 할 수 없다는 것을 알았습니다.지구상의 한 점이 범위 내에있는 경우 빠른 근사값

지구상의 두 지점을 확인하는 다른 방법이 있습니까? 범위가 x 미터 일 수 있습니까? 메서드가 정확할 필요는 없지만, 빠르지 않으면 거리가 < = x이면 true를 반환해야합니다. 또한 distance> x 인 경우 true를 반환 할 수 있습니다 (그러나 항상 true를 반환하지는 않음).

내 테스트 코드 (LinqPad) 곡률 무시할 단거리의 경우

void Main() 
{ 
    var lat = 53.553072; 
    var lng = 9.993023; 

    var lat0 = 53.553073; 
    var lng0 = 9.993178; 

    "Google Maps: 10.02m".Dump(); // 10.02m 
    $"Euclid: {DistanceEuclid(lat, lng, lat0, lng0)}m".Dump(); // 10,2396639400397m 
    $"Haversine: {DistanceHaversine(lat, lng, lat0, lng0)}m".Dump(); // 10,2396637520237m 
} 

const int R = 6371000; 
const double PiBy180 = Math.PI/180; 
const double deglen = 111194.93; 

double DistanceEuclid(double lat, double lng, double lat0, double lng0) 
{ 
    var x = lat - lat0; 
    var y = (lng - lng0)*Math.Cos(ToRadians(lat0)); 
    return deglen*Math.Sqrt(x*x + y*y); 
} 

public double DistanceHaversine(double lat, double lng, double lat0, double lng0) 
{ 
    var lat1 = ToRadians(lat); 
    var lat2 = ToRadians(lat0); 
    var dLat = ToRadians(lat0 - lat); 
    var dLng = ToRadians(lng0 - lng); 
    var h = Math.Sin(dLat/2) * Math.Sin(dLat/2) + Math.Cos(lat1) * Math.Cos(lat2) * Math.Sin(dLng/2) * Math.Sin(dLng/2); 
    var c = 2 * Math.Atan2(Math.Sqrt(h), Math.Sqrt(1 - h)); 
    return R * c; 
} 

double ToRadians(double degrees) => degrees * PiBy180; 
+0

[this] (http://stackoverflow.com/questions/11555355/calculating-the-distance-between-2-points) 또는 [this] (http://stackoverflow.com/questions/)을 보았습니까? 6182005/2 포인트 사이의 거리) 또는 [this] (http://www.geodatasource.com/developers/c-sharp) 또는 [this] (http://www.vcskicks.com/code-snippet/) distance-formula.php)? –

+1

또는 [this] (http://jonisalonen.com/2014/computing-distance-between-coordinates-can-be-simple-and-fast/) – Gene

+0

@MikeEason 첫 번째 링크는 Haversine 수식을 사용하고 다른 두 개는 x/y 좌표를 사용하여 점 사이의 거리를 계산하는 데 사용되지만 위도/경도가 있습니다. – wertzui

답변

0

, 당신은 직선 근사를 사용하고 점 사이의 유클리드 거리를 취할 수있다.

곡률 문제가 시간 경과에 따라 명확한 원호 길이에 대해 회전 타원체 (즉, 지구)상의 점 사이에서 원호 길이를 사전 계산하는 것을 포함 할 수있는 장거리 측정에 대한 빠르고 더러운 접근법. 예를 들어, 거리가 동일하기 때문에 세로 (수직) 축에 대한 반구에 대해 Φ0, Φ1 및 Δλ (| λ0-λ1 |)의 양자화 된 값을 근사값으로 찾기 위해 배열/룩업 테이블을 만듭니다. 평등하고 반대되는 종 방향 차이. 배열의 크기를 늘리면 정확도를 높일 수 있습니다. 메모리 예산이 부족한 경우 매우 크게 만들 수 있습니다.

특정 데이터 구조 나 수정 공식을 사용하여 근사 정확도를 향상시킬 수는 있지만 확실하지 않습니다.

그런 다음 항목과 플레이어 간의 거리와 거리를 비교할 수 있습니다.