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的更多相关文章

  1. 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 ...

  2. (转) [it-ebooks]电子书列表

    [it-ebooks]电子书列表   [2014]: Learning Objective-C by Developing iPhone Games || Leverage Xcode and Obj ...

  3. 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 ...

  4. Netron开发快速上手(一):GraphControl,Shape,Connector和Connection

    版权所有,引用请注明出处:<<http://www.cnblogs.com/dragon/p/5203663.html >> 本文所用示例下载FlowChart.zip 一个用 ...

  5. 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 ...

  6. How parse REST service JSON response

    1. get JSON responses and go to : http://json2csharp.com/ 2. write data contracts using C# All class ...

  7. Unsupervised Classification - Sprawl Classification Algorithm

    Idea Points (data) in same cluster are near each others, or are connected by each others. So: For a ...

  8. PhoneGap API Documentation API Reference

    API Reference-API参考 Accelerometer-加速度计 Tap into the device's motion sensor.-点击进入该设备的运动传感器. Camera-相机 ...

  9. Upgrade Guide

    Upgrade Guide This guide will point out the key points to be aware of when upgrading to version 3. A ...

随机推荐

  1. TCP和UDP协议的应用/参数查看

    TCP发送的包有序号,对方收到包后要给一个反馈,如果超过一定时间还没收到反馈就自动执行超时重发,因此TCP最大的优点是可靠.一般网页(http).邮件(SMTP).远程连接(Telnet).文件(FT ...

  2. javascript精确计算

    一篇文章: 4 个用于执行高级数学计算的 JavaScript 库 numbers.js  Numeric Javascript accounting.js Tangle 有时只需要加减乘法能精确,没 ...

  3. linux用VSFTP搭建FTP服务器

    一般在各种linux的发行版中,默认带有的ftp软件是vsftp,从各个linux发行版对vsftp的认可可以看出,vsftp应该是一款不错的ftp软件. sudo apt-get install v ...

  4. java单元测试(使用junit)

    JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework),供Java开发人员编写单元测试之用. 1.概述 Ju ...

  5. BZOJ_1627_[Usaco2007_Dec]_穿越泥地_(bfs)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1627 网格图,给出起点,终点,障碍,求最短路. 分析 简单的宽搜. #include < ...

  6. UVa 1153 Keep the Customer Satisfied 【贪心 优先队列】

    题意:给出n个工作,已知每个工作需要的时间last,以及截止时间end,(必须在截止时间之前完成)问最多能够完成多少个工作 首先预处理,将这n件任务按照截止时间从小到大排序 然后用一个cur记录当前做 ...

  7. jquery图表插件morris.js参数详解和highcharts图表插件

    一.morris.js 优点:轻巧.简单好用 缺点:没highcharts功能多,常用的足以 网址:http://morrisjs.github.io/morris.js/ 核心代码 1.head调用 ...

  8. Leap Motion 开发笔记

    Leap Motion 体系架构 Leap Motion支持所有主流操作系统,leap motion在Windows系统下是作为一个服务运行的,在Mac和Linux是后台守护进程.软件通过USB线连接 ...

  9. I.MX6 Android netperf

    /***************************************************************************** * I.MX6 Android netpe ...

  10. 物联网操作系统HelloX开发者入门指南

    HelloX开发者入门指南 HelloX是聚焦于物联网领域的操作系统开发项目,可以通过百度搜索"HelloX",获取详细信息.当前开发团队正在进一步招募中,欢迎您的了解和加入.如果 ...