Calculating a bearing between points in location-aware apps
https://software.intel.com/en-us/blogs/2012/11/30/calculating-a-bearing-between-points-in-location-aware-apps
Submitted by John Mechalas (... on Fri, 11/30/2012 - 08:37
Earlier this week I wrote about how to calculate the distance between two points in a location-aware app. Today, I am going to discuss a related topic: how to calculate the bearing between two points.
Like the shortest-distance problem, the bearing between two points on the globe is calculated using the great circle arc that connects them. With the exception of lines of latitude and longitude, great circle arcs do not follow a constant direction relative to true north and this means that as you travel along the arc your heading will vary.
This is made clear in the figure below, which is a gnomonic projection of the earth, showing our route from Portland to London (the gnomonic projection has a very special property: straight lines on the map correspond to great circle arcs). As you can see, the direction of travel changes along the path. The initial bearing, or forward azimuth, is about 33.6° but the final bearing as we approach London is about 141.5°.
As you travel along a great circle route your bearing to your destination changes. The dotted lines represent the direction of true north relative to the starting and ending points.
To calculate the initial bearing bearing we use the following formula. Note the use of the two-argument form of the arctangent, atan2(y,x), which ensures that the resulting angle is in the correct quadrant:
Θ = atan2( sin(Δλ) * cos(Φ2), cos(Φ1) * sin (Φ2) * cos(Δλ) )
This function will return the angle in radians from -π to π but what we want is an angle in degrees from 0 to 360. To accomplish this, we convert to degrees, add 360, and take the modulo 360:
Θd = ( Θ * 180 / π + 360 ) % 360
To get the final bearing, you reverse the latitudes and longitudes, and then take the angle that is in the opposite direction (180 degrees around).
Unlike our great circle distance calculation, the bearing calculation makes use of atan and it contains a singularity: when the two points converge, the angle becomes undefined. This makes perfect sense in the physical world, as if the source and the destination are exactly the same then there is no bearing between them. In practice, rounding errors would probably prevent a perfect equality from occurring, but it would still be good form to assume the points are coincident if their distance is below a threshold distance of a meter or two.
Code
Below are some code snippets that can be used to calculate the bearing between two points. You pass the latitude and longitude (in decimal degrees) for the first point as lat1 and long1, and for the second point in lat2 and long2.
For Windows developers, here is an implementation in C#:
class GreatCircleBearing
{
static Double degToRad = Math.PI / 180.0; static public Double initial (Double lat1, Double long1, Double lat2, Double long2)
{
return (_bearing(lat1, long1, lat2, long2) + 360.0) % ;
} static public Double final(Double lat1, Double long1, Double lat2, Double long2)
{
return (_bearing(lat2, long2, lat1, long1) + 180.0) % ;
} static private Double _bearing(Double lat1, Double long1, Double lat2, Double long2)
{
Double phi1 = lat1 * degToRad;
Double phi2 = lat2 * degToRad;
Double lam1 = long1 * degToRad;
Double lam2 = long2 * degToRad; return Math.Atan2(Math.Sin(lam2-lam1)*Math.Cos(phi2),
Math.Cos(phi1)*Math.Sin(phi2) - Math.Sin(phi1)*Math.Cos(phi2)*Math.Cos(lam2-lam1)
) * /Math.PI;
}
}
And in Javascript:
function bearingInitial (lat1, long1, lat2, long2)
{
return (bearingDegrees(lat1, long1, lat2, long2) + 360) % 360;
} function bearingFinal(lat1, long1, lat2, long2) {
return (bearingDegrees(lat2, long2, lat1, long1) + 180) % 360;
} function bearingDegrees (lat1, long1, lat2, long2)
{
var degToRad= Math.PI/180.0; var phi1= lat1 * degToRad;
var phi2= lat2 * degToRad;
var lam1= long1 * degToRad;
var lam2= long2 * degToRad; return Math.atan2(Math.sin(lam2-lam1) * Math.cos(phi2),
Math.cos(phi1)*Math.sin(phi2) - Math.sin(phi1)*Math.cos(phi2)*Math.cos(lam2-lam1)
) * 180/Math.PI;
}
And for Android developers, an implementation in Java:
class GreatCircleBearing
{
static public double initial (double lat1, double long1, double lat2, double long2)
{
return (_bearing(lat1, long1, lat2, long2) + 360.0) % 360;
} static public double final(double lat1, double long1, double lat2, double long2)
{
return (_bearing(lat2, long2, lat1, long1) + 180.0) % 360;
} static private double _bearing(double lat1, double long1, double lat2, double long2)
{
static double degToRad = Math.PI / 180.0;
double phi1 = lat1 * degToRad;
double phi2 = lat2 * degToRad;
double lam1 = long1 * degToRad;
double lam2 = long2 * degToRad; return Math.atan2(Math.sin(lam2-lam1)*Math.cos(phi2),
Math.cos(phi1)*Math.sin(phi2) - Math.sin(phi1)*Math.cos(phi2)*Math.cos(lam2-lam1)
) * 180/Math.PI;
}
}
As with our distance calculations, the assumption behind these formulas is a spherical earth. This is sufficiently accurate for casual use but scientific applications will need a more sophisticated model.
Calculating a bearing between points in location-aware apps的更多相关文章
- How To Start Building Spatially Aware Apps With Google’s Project Tango
How To Start Building Spatially Aware Apps With Google’s Project Tango “Tango can enable a whole new ...
- (转) [it-ebooks]电子书列表
[it-ebooks]电子书列表 [2014]: Learning Objective-C by Developing iPhone Games || Leverage Xcode and Obj ...
- spring boot上传文件错误The temporary upload location [/tmp/tomcat.5260880110861696164.8090/work/Tomcat/localhost/ROOT] is not valid
参考了:https://www.jianshu.com/p/cfbbc0bb0b84 再次感谢,但还是有些调整 一.在zuul服务中加入两个配置参数(location: /data/apps/temp ...
- Netron开发快速上手(一):GraphControl,Shape,Connector和Connection
版权所有,引用请注明出处:<<http://www.cnblogs.com/dragon/p/5203663.html >> 本文所用示例下载FlowChart.zip 一个用 ...
- infoq - neo4j graph db
My name is Charles Humble and I am here at QCon New York 2014 with Ian Robinson. Ian, can you introd ...
- How parse REST service JSON response
1. get JSON responses and go to : http://json2csharp.com/ 2. write data contracts using C# All class ...
- Unsupervised Classification - Sprawl Classification Algorithm
Idea Points (data) in same cluster are near each others, or are connected by each others. So: For a ...
- PhoneGap API Documentation API Reference
API Reference-API参考 Accelerometer-加速度计 Tap into the device's motion sensor.-点击进入该设备的运动传感器. Camera-相机 ...
- Upgrade Guide
Upgrade Guide This guide will point out the key points to be aware of when upgrading to version 3. A ...
随机推荐
- php无法上传大文件完美解决方案
php.ini无法上传大文件完美解决办法 1.打开php.ini(打开方式就不用说了,百度一大堆) 2.查找post_max_size 表单提交最大数值,此项不是限制上传单个文件的大小,而是针对整个表 ...
- UIColor的用法
UIColor,CGColor,CIColor的区别和联系 layer.shadowColor = [UIColor redColor].CGColor; 这个是今天用到的.顺便总结一下. 1.UIC ...
- Linux命令之chmod 及+s 参数(临时以所有者权限执行)
转自: http://blog.csdn.net/shaobingj126/article/details/7031221 chmod用于改变文件或目录的访问权限.用户用它控制文件或目录的访问权限.该 ...
- Effective C++学习笔记 条款05:了解C++默默编写并调用的哪些函数
一.如果用户没有提供构造函数.copy构造函数.copy assignment操作符和析构函数,当且仅当这些函数被需要的时候,编译器才会帮你创建出来.编译器生成的这些函数都是public且inline ...
- Jquery 弹出新窗体
开始先用css将这个DIV设好位置,并且隐藏 function winshow() { var winNode = $(".win"); winNode.show("sl ...
- bzoj2324营救皮卡丘
费用流. 建图比较重要. 1.S->id[0][0] flow=k. 表示k条路径. 2.S->id[i][0] flow=1, 每次消耗1流量就补充1流量. 3.id[i][1]-> ...
- Google发布SSLv3漏洞简要分析报告
今天上午,Google发布了一份关于SSLv3漏洞的简要分析报告.根据Google的说法,该漏洞贯穿于所有的SSLv3版本中,利用该漏洞,黑客可以通过中间人攻击等类似的方式(只要劫持到的数据加密两端均 ...
- UVa 10054 The Necklace【欧拉回路】
题意:给出n个珠子,珠子颜色分为两半,分别用1到50之间的数字表示, 现在给出n个珠子分别的颜色,问是否能够串成一个环.即为首尾相连,成为一个回路 判断是否构成一个环,即判断是否为欧拉回路,只需要判断 ...
- php复制目录及文件
<?php /* 复制目录 */ function copydir($dirsrc,$dirto){ if(is_file($dirto)){ echo "目标不是目录不能创建&quo ...
- POJ 1833 排列
题意: 给你某个排列 求从下一个排列开始的第k个排列如果是最后一个排列 则下一个排列为1 2 3 ... n// 1 用stl 里面的 next_permutation// 2 用生成下一个排列算法/ ...
