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 ...
随机推荐
- windows和linux共享文件
一篇文章: 环境:主机操作系统 是Windows XP ,虚拟机 是Ubuntu 9.10,虚拟机是VirtualBox 3.08. 1. 安装增强功能包(Guest Additions) 安装好Ub ...
- 从输入 URL 到页面加载完的过程中都发生了什么---优化
这篇文章是转载自:安度博客,http://www.itbbu.com/1490.html 在很多地方看到,感觉不错,理清了自己之前的一些思路,特转过来留作记录. 一个HTTP请求的过程 为了简化我们先 ...
- Collection_Compare
冒泡 package com.bjsxt.sort.bubble; import java.util.Arrays; public class BubbleSort1 { /** * @param a ...
- POJ 2449 A*+SPFA
A*算法求第k短路流程: 1)计算h[],即当前点到t的估计值 若为有向图,建立反向图求出h[].若为无向图,可直接求解h[].可通过SPFA求解. 2)A*搜索 每次找到新节点就直接加入队列,计算出 ...
- BootStrap图标
- BootStrap基本样式
文本对齐风格:.text-left:左对齐.text-center:居中对齐.text-right:右对齐.text-justify:两端对齐 取消列表符号:.list-unstyled内联列表:.l ...
- bzoj4048 3928
羞耻,分组赛上考的,竟然没想出来, 对坐标离散化后区间dp即可,竟然还双倍经验 ; ..,..] of longint; v:..] of longint; a,b,h:..] of longint; ...
- Asp.Net时间戳与时间互转
/// <summary> /// 时间戳转成时间类型 /// </summary> /// <param name="timeStamp">& ...
- ajax上传图片 jquery插件 jquery.form.js 的方法 ajaxSubmit; AjaxForm与AjaxSubmit的差异
先引入脚本 这里最好是把jquery的脚本升级到1.7 <script src="js/jquery-1.7.js" type="text/javascript& ...
- QPS、PV和需要部署机器数量计算公式(转)
术语说明: QPS = req/sec = 请求数/秒 [QPS计算PV和机器的方式] QPS统计方式 [一般使用 http_load 进行统计] QPS = 总请求数 / ( 进程总数 * 请求 ...