double computeHeading(double latitude1, double longitude1, double latitude2, double longitude2)
{
double degToRad = PI / 180.0;
double phi1 = latitude1*degToRad;
double phi2 = latitude2*degToRad;
double lam1 = longitude1*degToRad;
double lam2 = longitude2*degToRad;
double x,y;
x = cos(phi2) * sin(lam2-lam1);
printf("X is %lf\n", x);
y = cos(phi1) * sin(phi2) - sin(phi1) * cos(phi2) * cos(lam2-lam1);
printf("Y is %lf\n", y);
return atan2(x,y)*180/PI;
}
我使用上面的函数来确定两个地理坐标之间的真实方位。
我目前正在开发一个小的导航小部件,它使用来自Android传感器的GPS数据。这个小部件有一个箭头指向一个远离设备当前位置的点。箭头的方向随设备的当前位置和方位角而改变,以始终面向远处的点。
下面是一个场景:
我在一个地方,朝北,另一个地方的方位角是300度(在我的西北方向)。如果我面朝南,不动,我与远处的相对方位应该是120度。
如何计算相对方位角(方位角)?
最佳答案
有几种方法可以解决这个问题。第一个假设地球是球形的,这就是你看起来在做的事情。利用Haversine公式计算了大圆导航的相对方位。在给定起点和终点的情况下,该公式会找到通过两点的大圆。由此可计算出初始轴承。这条大圆路线是两点之间的最短路线,但由于受到这个问题的困扰,一般情况下,沿途的方位不会恒定。此外,除了在某些非常特殊的情况下,反向轴承的行为不像您所期望的那样,如果您想确定它的一般情况下,您将不得不执行另一个计算反向的起点和终点。
你可以使用的另一种方法是Rhumb线公式。在这种情况下,起点和终点之间的方位角是恒定的,如果你愿意的话,你可以用你的关系来进行反向运动。由于这通常不同于大圆距离,遵循伦布线不会导致两点之间的最短路径,但它通过保持航向常数简化了导航。
这两种方法在Calculate distance, bearing and more between Latitude/Longitude points
另一种使用地球形状更精确表示的大圆导航公式是一种特殊类型的椭球,它归因于Vincenty以及Karney提供的附加增强。在这些情况下,公式是相当复杂的一点,可能是杀伤力过大的大多数应用,性能是相当差的哈维辛公式以上。但如果你需要的话,这些公式提供了更好的准确性。
更新:
根据下面的评论,主要的问题是弄清楚要走多远。这只是包含当前航向的大圆和所需航向的平面法线之间的角度。要在当前航向上获得该平面的法线,需要当前位置L
和距离当前航向一定距离的点C
。正常值就是V = L×C
。要计算包含沿所需航向的大圆的平面的法向,只需知道沿所需路线的一个点,该点已经以目的地点的形式存在,我们称之为D
。然后可以通过U = L×D
找到正常值。它们之间的夹角由θ = acos((U∙V)/(|U||V|))
给出。
要查找L
、C
和D
,必须转换Latitude, Longitude, Altitude (LLA) coordinates into Earth Centered, Earth Fixed (ECEF) coordinates。