使用余弦定律计算目标C中2点之间的距离?

时间:2010-01-13 00:27:27

标签: objective-c coordinate-systems cosine

我从Google地图获取了一些GPS坐标,我需要找到它们之间的距离 使用目标C.我已经实现了公式,但我得到的结果很大。

我已经测试了谷歌地图中的值,将它们传回谷歌地球和互联网上的地理编码服务,一切都结束了。我现在开始怀疑余弦定律要求我在传入之前用坐标进行某种转换。

我做了类似的Haversine公式的实现,但这也给了我很大的成果。然后我切换到余弦,因为它更容易调试,我不需要非常高的精度。

希望有人能对这一点有所了解,或者使用代码:)

- (CGFloat) calculateDistanceBetweenPoints:(CGPoint) origin andDestination:(CGPoint) destination {

//To convert kilometers to miles, divide by 1.609
// x = latitude 
// y = longitude

/* example:
 Dubai      : 25.248665, 55.352917 
 Amsterdam  : 52.309071, 4.763385
 Approx dist: 5,182.62 KM
 Calc. dist : 8,253.33
 */

CGFloat toRad           =   (M_PI / 180);
CGFloat R               =   6371.0f; //earth's mean radius in Km

CGFloat sinePart        =   sinf( origin.x * toRad ) * sinf( destination.x * toRad );
CGFloat cosinePart      =   cosf( origin.x * toRad ) * cosf( destination.x * toRad );
CGFloat deltaCosinePart =   cosf( ( destination.y - origin.y ) * toRad );

CGFloat delta           =   acosf( sinePart + cosinePart * deltaCosinePart) * R;

return delta;
}

以上根据此处引用的链接计算:stackoverflow question

5 个答案:

答案 0 :(得分:3)

您是否考虑过使用CLLocation中提供的方法:

- (CLLocationDistance)getDistanceFrom:(const CLLocation *)location

答案 1 :(得分:3)

有许多问题可能有所帮助,包括:

考虑到这两个位置,你在阿姆斯特丹创建一个球形三角形角A,在迪拜创建一个B角,在北极创建C角,边长a = 90° - φ Ams ,b = 90° - φ Dub ,角度C =Δλ=λ Dub - λ Ams 。要求的答案是c方。

使用我对SO 389211的回答中的一些材料。

这是一个彻底修改过的答案 - 我以前的尝试使用了错误的球形三角形,因此得到了错误的答案。


最糟糕的ASCII艺术:

                   + C (North Pole)
                  /|
                b/ |
                /  |
(Amsterdam) A  +   | a
                \  |
                c\ |
                  \|
                   + B (Dubai)

球面三角形的基本余弦定律是:

cos c = cos a . cos b + sin a . sin b . cos C

注意到cos(90º - x)= sin x和sin(90º - x)= cos x,我们可以写:

cos c =sinφ Ams 。 sinφ Dub +cosφ Ams 。 cosφ配音。 cosΔλ

然后通过乘以地球半径将弧度中的角度c转换为距离。


将此应用于您的数据:

Dubai:φ配音 = 25.248665°N,λ配音 = 55.352917°E
Amsterdam:φ Ams = 52.309071°N,λ Ams = 4.763385°E

Δλ = 50.589532°

三角法的小数位数为6位小数:

cos c = 0.426548 × 0.791320 + 0.904465 × 0.611402 × 0.634872
      = 0.337536            + 0.351079
      = 0.688615

何处:

c = 46.479426°
  =  0.811219 radians

将此乘以6371 km作为地球的名义半径

c = 5168 km

因此,对于R = 6371 km,距离为0.811219×6371 = 5168 km(至4 s.f。)。

TrueKnowledge说它应该是大约5155公里。它所使用的位置数据与您指定的值相当,维基百科确认您提供的半径。这是相当接近的 - 用相同的坐标重新计算,计算中的更多数字会产生更好的答案,但接近这一点。


答案 2 :(得分:2)

代码可能没问题,当我在你的示例数据上运行它(减去几个小数位)时,它返回5168.3584

答案 3 :(得分:1)

伙计们我很抱歉:(并且脸红了。 我对这些坐标做了一些其他的计算。我计算了他们的(x,y)位置 所以他们正确地将城市定位在我画的自定义地图上。这些坐标计算如下:

- (CGPoint) translateToPixelsFromLatitude:(CGFloat) latitude andLongitude:(CGFloat) longitude {

CGPoint position    = CGPointMake(0, 0);
CGFloat mapWidth    = 300.0f;
CGFloat mapHeight   = 200.0f;

CGFloat offsetX     = 5.0f;
CGFloat offsetY     = 35.0f;

position.x = (((180 + longitude) / 360) * mapWidth) + offsetX;
position.y = (mapHeight - (((90 + latitude) / 180) * mapHeight)) + offsetY;

return position;

}

有些人不应该在半夜编码,然后前往SO以获得忙碌人员的帮助,事故我将变换后的坐标传递给方法。

当我注意到在对不同城市进行地理编码时,我得到了非常相似的结果然后我阅读了hic3456的帖子,突然之间有意义了,我发现了这一点。

我记录并测试一个单独的类的坐标和距离,以便在将错误的数据传递给方法之前记录所有内容。

现在我真的希望除了我以外的人能从中受益。

再次抱歉,感谢你们每一个人。

答案 4 :(得分:0)

好吧,如果我正确地理解了这个问题,你就不会考虑地球的曲率。余弦定律在平面上工作,而不是在球面上。例如:如果您飞行,北极和南极相距约20,000公里,但如果您挖隧道,则只需约6000公里;)

问候,Ari