Implementation of position determination function - geopositioning

I'm attempting to implement position determination function of an aircraft to get "latitude/longitude azimuth"
I attached 3 images for summerized formula as you may see this is 5-step trigonometric equation (Steps 0/4) which is my aim to program. image1; image2 image3
To find aircraft coordinates there are defined 9 input parameters (image1): Station U and S latitude,longitude,altitude; Aircraft altitude and 2 slant ranges.
At the end of problem (image3) we will find 3 outputs: Aircraft latitude/longitude azimuth.

This code implements the solution explained for: How can I triangulate a position using two DMEs? on aviation.se. The code is in Python, which I happen to use instead of C, it's easy to convert into another language as required. I've broken down the calculation in smaller units to make code more legible and to ease your understanding.
The problem involves 3 points in 3D space: U and S are the DMEs, A is the aircraft.
As we just need the coordinates of U and S, to determinate A coordinates, I'm using coordinates of 3 well known DME stations. This will allow to check whether the result is correct. View based on the Low Altitude Enroute Chart:
When the program is run, the output is:
CAN: lat 49.17319, lon -0.4552778, alt 82
EVX: lat 49.03169, lon 1.220861, alt 152
P north: lat 49.386910325692874, lon 0.646650777948733, alt 296
P south: lat 48.78949175956114, lon 0.5265322105880027, alt 296
First are the coordinates of points U (CAN DME) and S (EVX DME) we entered, and
then two lines for the two possible location of the aircraft.
I made another test with DME at longer distance (1241 km for ARE and 557.1 km for GLA) which worked pretty good too:
ARE: lat 48.33264, lon -3.602472, alt 50
GLA: lat 46.40861, lon 6.244222, alt 1000
P north: lat 48.082101174246304, lon 13.210754399535269, alt 10
P south: lat 41.958725412109445, lon 9.470999690780628, alt 10
The actual location of the aircraft is supposed to be SZA navaid, in south of France: Lat 41.937°, lon 9.399°.
from math import asin, sqrt, cos, sin, atan2, acos, pi, radians, degrees
# Earth radius in meters (https://rechneronline.de/earth-radius/)
E_RADIUS = 6367 * 1000 # at 45°N - Adjust as required
def step_0(r_e, h_u, h_s, h_a, d_ua, d_sa):
# Return angular distance between each station U/S and aircraft
# Triangle UCA and SCA: The three sides are known,
a = (d_ua - h_a + h_u) * (d_ua + h_a - h_u)
b = (r_e + h_u) * (r_e + h_a)
theta_ua = 2 * asin(.5 * sqrt(a / b))
a = (d_sa - h_a + h_s) * (d_sa + h_a - h_s)
b = (r_e + h_s) * (r_e + h_a)
theta_sa = 2 * asin(.5 * sqrt(a / b))
# Return angular distances between stations and aircraft
return theta_ua, theta_sa
def step_1(lat_u, lon_u, lat_s, lon_s):
# Determine angular distance between the two stations
# and the relative azimuth of one to the other.
a = sin(.5 * (lat_s - lat_u))
b = sin(.5 * (lon_s - lon_u))
c = sqrt(a * a + cos(lat_s) * cos(lat_u) * b * b)
theta_us = 2 * asin(c)
a = lon_s - lon_u
b = cos(lat_s) * sin(a)
c = sin(lat_s) * cos(lat_u)
d = cos(lat_s) * sin(lat_u) * cos(a)
psi_su = atan2(b, c - d)
return theta_us, psi_su
def step_2(theta_us, theta_ua, theta_sa):
# Determine whether DME spheres intersect
if (theta_ua + theta_sa) < theta_us:
# Spheres are too remote to intersect
return False
if abs(theta_ua - theta_sa) > theta_us:
# Spheres are concentric and don't intersect
return False
# Spheres intersect
return True
def step_3(theta_us, theta_ua, theta_sa):
# Determine one angle of the USA triangle
a = cos(theta_sa) - cos(theta_us) * cos(theta_ua)
b = sin(theta_us) * sin(theta_ua)
beta_u = acos(a / b)
return beta_u
def step_4(ac_south, lat_u, lon_u, beta_u, psi_su, theta_ua):
# Determine aircraft coordinates
psi_au = psi_su
if ac_south:
psi_au += beta_u
else:
psi_au -= beta_u
# Determine aircraft latitude
a = sin(lat_u) * cos(theta_ua)
b = cos(lat_u) * sin(theta_ua) * cos(psi_au)
lat_a = asin(a + b)
# Determine aircraft longitude
a = sin(psi_au) * sin(theta_ua)
b = cos(lat_u) * cos(theta_ua)
c = sin(lat_u) * sin(theta_ua) * cos(psi_au)
lon_a = atan2(a, b - c) + lon_u
return lat_a, lon_a
def main():
# Program entry point
# -------------------
# For this test, I'm using three locations in France:
# VOR Caen, VOR Evreux and VOR L'Aigle.
# The angles and horizontal distances between them are known
# by looking at the low-altitude enroute chart which I've posted
# here: https://i.stack.imgur.com/m8Wmw.png
# We know there coordinates and altitude by looking at the AIP France too.
# For DMS <--> Decimal degrees, this tool is handy:
# https://www.rapidtables.com/convert/number/degrees-minutes-seconds-to-degrees.html
# Let's pretend the aircraft is at LGL
# lat = 48.79061, lon = 0.5302778
# Stations U and S are:
u = {'label': 'CAN', 'lat': 49.17319, 'lon': -0.4552778, 'alt': 82}
s = {'label': 'EVX', 'lat': 49.03169, 'lon': 1.220861, 'alt': 152}
# We know the aircraft altitude
a_alt = 296 # meters
# We know the approximate slant ranges to stations U and S
au_range = 45 * 1852 # 1 NM = 1,852 m
as_range = 31 * 1852
# Compute angles station - earth center - aircraft for U and S
# Expected values UA: 0.0130890288 rad
# SA: 0.0090168045 rad
theta_ua, theta_sa = step_0(
r_e=E_RADIUS, # Earth
h_u=u['alt'], # Station U altitude
h_s=s['alt'], # Station S altitude
h_a=a_alt, d_ua=au_range, d_sa=as_range # aircraft data
)
# Compute angle between station, and their relative azimuth
# We need to convert angles into radians
theta_us, psi_su = step_1(
lat_u=radians(u['lat']), lon_u=radians(u['lon']), # Station U coordinates
lat_s=radians(s['lat']), lon_s=radians(s['lon'])) # Station S coordinates
# Check validity of ranges
if not step_2(
theta_us=theta_us,
theta_ua=theta_ua,
theta_sa=theta_sa):
# Cannot compute, spheres don't intersect
print('Cannot compute, ranges are not consistant')
return 1
# Solve one angle of the USA triangle
beta_u = step_3(
theta_us=theta_us,
theta_ua=theta_ua,
theta_sa=theta_sa)
# Compute aircraft coordinates.
# The first parameter is whether the aircraft is south of the line
# between U and S. If you don't know, then you need to compute
# both, once with ac_south = False, once with ac_south = True.
# You will get the two possible positions, one must be eliminated.
# North position
lat_n, lon_n = step_4(
ac_south=False, # See comment above
lat_u=radians(u['lat']), lon_u=radians(u['lon']), # Station U
beta_u=beta_u, psi_su=psi_su, theta_ua=theta_ua # previously computed
)
pn = {'label': 'P north', 'lat': degrees(lat_n), 'lon': degrees(lon_n), 'alt': a_alt}
# South position
lat_s, lon_s = step_4(
ac_south=True,
lat_u=radians(u['lat']), lon_u=radians(u['lon']),
beta_u=beta_u, psi_su=psi_su, theta_ua=theta_ua)
ps = {'label': 'P south', 'lat': degrees(lat_s), 'lon': degrees(lon_s), 'alt': a_alt}
# Print results
fmt = '{}: lat {}, lon {}, alt {}'
for p in u, s, pn, ps:
print(fmt.format(p['label'], p['lat'], p['lon'], p['alt']))
# The expected result is about:
# CAN: lat 49.17319, lon -0.4552778, alt 82
# EVX: lat 49.03169, lon 1.220861, alt 152
# P north: lat ??????, lon ??????, alt 296
# P south: lat 48.79061, lon 0.5302778, alt 296
if __name__ == '__main__':
main()

Related

Determining if a point lies between two bearings from a central point

I am trying to determine if a point lies between two bearings from a central point.
The diagram below attempts to explain things
I have a central point labelled A
I have two points (labelled B & C) which provide the boundaries of the search area (based on bearing only - there is no distance element required).
I'm trying to determine if point D is within the sector formed by A-B and A-C
I've calculated the bearings from A to each B & C
In my real scenario the angle created between the bearings can be anything from 0 to 360.
There are some similar questions & answers
however in my case I'm not interested in restricting my search to the radius of a circle. And there seems to be some implementation issues around angle size and the location of the points in terms of clockwise vs counter-clockwise
It seems so simple in theory but my maths is clearly not up to scratch :(
Any advice or pseudo-code would be greatly appreciated.
Here would be my approach:
calculate first bearing angle X
calculate second bearing angle Y
calculate angle Z towards point D
if X < Z < Y, return true; otherwise, return false
In your example it looks like you'd calculate Z ~ 90deg and find 45 < 90 < 135 (is your picture wrong? is says 315).
You can use something like the "atan2" function in whatever language you're using. This is an extension of the basic arctangent function which takes not just the slope but both the rise and run and instead of returning an angle from only a 180-degree range, it returns the true angle from a 360-degree range. So
Z = atan2(Dy, Dx)
Should give you the angle (possibly in radians; be careful) that you can compare to your bearings to tell whether you're inside the search. Note that the order of X and Y matter since the order is what defines which of the two sections is in the search area (X to Y gives ~90 deg in your picture, but Y to X gives ~270 deg).
You can calculate and compare the cross products of the vectors (AB X BD), and (AC X CD).
if (AB X BD) > 0, you have a counter clock wise turn
if (AC X CD) < 0, you have a clock wise turn
If both above tests are true, then the point D is in the sector BAC
This allows you to completely avoid using expensive trig functions.
class Point:
"""small class for point arithmetic convenience
"""
def __init__(self, x: float = 0, y: float = 0) -> None:
self.x = x
self.y = y
def __sub__(self, other: 'Point') -> 'Vector':
return Vector(self.x - other.x, self.y - other.y)
class Vector:
"""small class for vector arithmetic convenience
"""
def __init__(self, x: float = 0, y: float = 0) -> None:
self.x = x
self.y = y
def cross(self, other: 'Vector') -> float:
return (self.x * other.y) - (self.y * other.x)
def in_sector(A: Point, B: Point, C: Point, D: Point) -> bool:
# construct vectors:
ab = B - A
bd = D - B
ac = C - A
cd = D - C
print(f'ab x bc = {ab.cross(bd)}, ac x cd = {ac.cross(cd)}')
return ab.cross(bd) > 0 and ac.cross(cd) < 0
if __name__ == '__main__':
A = Point(0, 0)
B = Point(1, 1)
C = Point(-1, 1)
D = Point(0, 1)
print(f'D in sector ABC: {in_sector(A, B, C, D)}', end='\n\n')
print(f'D in sector ACB: {in_sector(A, C, B, D)}') # inverting the sector definition so D is now outside
Output:
ab x bc = 1, ac x cd = -1
D in sector ABC: True
ab x bc = -1, ac x cd = 1
D in sector ACB: False

Plot a point in 3D space perpendicular to a line vector

I'm attempting to calculate a point in 3D space which is orthogonal/perpendicular to a line vector.
So I have P1 and P2 which form the line. I’m then trying to find a point with a radius centred at P1, which is orthogonal to the line.
I'd like to do this using trigonometry, without any programming language specific functions.
At the moment I'm testing how accurate this function is by potting a circle around the line vector.
I also rotate the line vector in 3D space to see what happens to the plotted circle, this is where my results vary.
Some of the unwanted effects include:
The circle rotating and passing through the line vector.
The circle's radius appearing to reducing to zero before growing as the line vector changes direction.
I used this question to get me started, and have since made some adjustments to the code.
Any help with this would be much appreciated - I've spent 3 days drawing circles now. Here's my code so far
//Define points which form the line vector
dx = p2x - p1x;
dy = p2y - p1y;
dz = p2z - p1z;
// Normalize line vector
d = sqrt(dx*dx + dy*dy + dz*dz);
// Line vector
v3x = dx/d;
v3y = dy/d;
v3z = dz/d;
// Angle and distance to plot point around line vector
angle = 123 * pi/180 //convert to radians
radius = 4;
// Begin calculating point
s = sqrt(v3x*v3x + v3y*v3y + v3z*v3z);
// Calculate v1.
// I have been playing with these variables (v1x, v1y, v1z) to try out different configurations.
v1x = s * v3x;
v1y = s * v3y;
v1z = s * -v3z;
// Calculate v2 as cross product of v3 and v1.
v2x = v3y*v1z - v3z*v1y;
v2y = v3z*v1x - v3x*v1z;
v2z = v3x*v1y - v3y*v1x;
// Point in space around the line vector
px = p1x + (radius * (v1x * cos(angle)) + (v2x * sin(angle)));
py = p1y + (radius * (v1y * cos(angle)) + (v2y * sin(angle)));
pz = p1z + (radius * (v1z * cos(angle)) + (v2z * sin(angle)));
EDIT
After wrestling with this for days while in lockdown, I've finally managed to get this working. I'd like to thank MBo and Futurologist for their invaluable input.
Although I wasn't able to get their examples working (more likely due to me being at fault), their answers pointed me in the right direction and to that eureka moment!
The key was in swapping the correct vectors.
So thank you to you both, you really helped me along with this. This is my final (working) code:
//Set some vars
angle = 123 * pi/180;
radius = 4;
//P1 & P2 represent vectors that form the line.
dx = p2x - p1x;
dy = p2y - p1y;
dz = p2z - p1z;
d = sqrt(dx*dx + dy*dy + dz*dz)
//Normalized vector
v3x = dx/d;
v3y = dy/d;
v3z = dz/d;
//Store vector elements in an array
p = [v3x, v3y, v3z];
//Store vector elements in second array, this time with absolute value
p_abs = [abs(v3x), abs(v3y), abs(v3z)];
//Find elements with MAX and MIN magnitudes
maxval = max(p_abs[0], p_abs[1], p_abs[2]);
minval = min(p_abs[0], p_abs[1], p_abs[2]);
//Initialise 3 variables to store which array indexes contain the (max, medium, min) vector magnitudes.
maxindex = 0;
medindex = 0;
minindex = 0;
//Loop through p_abs array to find which magnitudes are equal to maxval & minval. Store their indexes for use later.
for(i = 0; i < 3; i++) {
if (p_abs[i] == maxval) maxindex = i;
else if (p_abs[i] == minval) minindex = i;
}
//Find the remaining index which has the medium magnitude
for(i = 0; i < 3; i++) {
if (i!=maxindex && i!=minindex) {
medindex = i;
break;
}
}
//Store the maximum magnitude for now.
storemax = (p[maxindex]);
//Swap the 2 indexes that contain the maximum & medium magnitudes, negating maximum. Set minimum magnitude to zero.
p[maxindex] = (p[medindex]);
p[medindex] = -storemax;
p[minindex] = 0;
//Calculate v1. Perpendicular to v3.
s = sqrt(v3x*v3x + v3z*v3z + v3y*v3y);
v1x = s * p[0];
v1y = s * p[1];
v1z = s * p[2];
//Calculate v2 as cross product of v3 and v1.
v2x = v3y*v1z - v3z*v1y;
v2y = v3z*v1x - v3x*v1z;
v2z = v3x*v1y - v3y*v1x;
//For each circle point.
circlepointx = p2x + radius * (v1x * cos(angle) + v2x * sin(angle))
circlepointy = p2y + radius * (v1y * cos(angle) + v2y * sin(angle))
circlepointz = p2z + radius * (v1z * cos(angle) + v2z * sin(angle))
Your question is too vague, but I may suppose what you really want.
You have line through two point p1 and p2. You want to build a circle of radius r centered at p1 and perpendicular to the line.
At first find direction vector of this line - you already know how - normalized vector v3.
Now you need arbitrary vector perpendicular to v3: find components of v3 with the largest magnitude and with the second magnitude. For example, abs(v3y) is the largest and abs(v3x) has the second magnitude. Exchange them, negate the largest, and make the third component zero:
p = (-v3y, v3x, 0)
This vector is normal to v3 (their dot product is zero)
Now normalize it
pp = p / length(p)
Now get binormal vector as cross product of v3 and pp (I has unit length, no need to normalize), it is perpendicular to both v3 and pp
b = v3 x pp
Now build needed circle
circlepoint(theta) = p1 + radius * pp * Cos(theta) + radius * b * Sin(theta)
Aslo note that angle in radians is
angle = degrees * pi / 180
#Input:
# Pair of points which determine line L:
P1 = [x_P1, y_P1, z_P1]
P2 = [x_P1, y_P1, z_P1]
# Radius:
Radius = R
# unit vector aligned with the line passing through the points P1 and P2:
V3 = P1 - P2
V3 = V3 / norm(V3)
# from the three basis vectors, e1 = [1,0,0], e2 = [0,1,0], e3 = [0,0,1]
# pick the one that is the most transverse to vector V3
# this means, look at the entries of V3 = [x_V3, y_V3, z_V3] and check which
# one has the smallest absolute value and record its index. Take the coordinate
# vector that has 1 at that selected index. In other words,
# if min( abs(x_V3), abs(y_V)) = abs(y_V3),
# then argmin( abs(x_V3), abs(y_V3), abs(z_V3)) = 2 and so take e = [0,1,0]:
e = [0,0,0]
i = argmin( abs(V3[1]), abs(V3[2]), abs(V3[3]) )
e[i] = 1
# a unit vector perpendicular to both e and V3:
V1 = cross(e, V3)
V1 = V1 / norm(V1)
# third unit vector perpendicular to both V3 and V1:
V2 = cross(V3, V1)
# an arbitrary point on the circle (i.e. equation of the circle with parameter s):
P = P1 + Radius*( np.cos(s)*V1 + np.sin(s)*V2 )
# E.g. say you want to find point P on the circle, 60 degrees relative to vector V1:
s = pi/3
P = P1 + Radius*( cos(s)*V1 + sin(s)*V2 )
Test example in Python:
import numpy as np
#Input:
# Pair of points which determine line L:
P1 = np.array([1, 1, 1])
P2 = np.array([3, 2, 3])
Radius = 3
V3 = P1 - P2
V3 = V3 / np.linalg.norm(V3)
e = np.array([0,0,0])
e[np.argmin(np.abs(V3))] = 1
V1 = np.cross(e, V3)
V1 = V1 / np.linalg.norm(V3)
V2 = np.cross(V3, V1)
# E.g., say you want to rotate point P along the circle, 60 degrees along rel to V1:
s = np.pi/3
P = P1 + Radius*( np.cos(s)*V1 + np.sin(s)*V2 )

I have a zip of x and y coordinates that show a path of a particle, How do I animate this path

I have a zip of x and y coordinates, example:
a = [(2.9552e-13, 5.00000000000000e-15),(2.8592e-13, 5.0003e-15),(2.7634e-13, 5.0008e-15),(2.6677e-13, 5.0017e-15),(2.5722e-13, 5.0030e-15),(2.4770e-13, 5.0046e-15),(2.3819e-13, 5.0067e-15),(2.2871e-13, 5.0093e-15),(2.1926e-13, 5.0125e-15)]
How do I show an animation in the 2d plane of a point as it changes through these points?
I finally did it and this is how i did it, i know the t==0 case in the points function is redundant.
def trajectory(EMeV=7.7, z1=2, z2=79, m1=4.0, xf=5, yf=0.3):
"""
EMeV: energy in MeV
z1,z2: atomic number of projectile and target respectively
xf: the projectile starts at xf*d away, where d is distance of closest approach
yf: the projectile starts at yf*d from the X-axis
m1: mass of projectile in amu
"""
# setup initial values
q = 1.602e-19 # [C], electronic charge
q1 = z1*q # [C], charge on q1
q2 = z2*q # [C], charge on q1
EJ = EMeV*1e6*q # [J], kinetic energy
u = 1.66e-27 # [kg], amu
m = m1*u # [kg], mass of projectile
v = sqrt(2*EJ/m) # speed of projectile
k = 8.99e9 # [m/F], coulomb's constant
d = k*q1*q2/EJ # [m], minimum distance of closest approach
rmax = xf*d # [m], maximum of x-values
# dynamic values
x = rmax # [m]
y = yf*d # [m]
vx = -v # [m/s]
vy = 0 # [m/s]
t = 0 # [s]
h = x/v/100 # [s], estimate a small time step
points = [(x,y)]
while (x<=rmax) and (x>=-rmax) and (y<=rmax) and (y>=-rmax):
r2 = x*x+y*y
E = k*q2/r2
F = q1*E
theta = arctan2(y,x)
# first do x
ax = F*cos(theta)/m
x += h*vx
vx += h*ax
# then y
ay = F*sin(theta)/m
y += h*vy
vy += h*ay
points.append( (x,y))
t += h
return points
Another piece of code
def point(t):
if (t==0):
a = circle((x[0],y[0]),1.3e-15,fill = true, rgbcolor='red')
if (t>0 and t<len(x)):
a = circle((x[3*t],y[3*t]),1.3e-15, fill = true, rgbcolor='red')
return a
a = animate([plot(point(t)) for t in sxrange(0,60,1)],xmin=-0.2e-13,ymin=-0.2e-
13,xmax=1.5e-13,ymax=8e-14)
b = animate([plot(circle((0,0),0.5e-14,fill=true)) for t in sxrange(0,60,1)],xmin=-0.2e-13,ymin=-0.2e-13,xmax=1.5e-13,ymax=8e-14)
c = a+b
c.show()
This is the Resultant graph of the path

R code runs too slow, how to speed and rewrite this code

The stu.csv contains 850,000 rows and 3 columns. The 2nd column is the longitude of ID, the 3rd column is the latitude of ID. The data in stu.csv file is like this:
ID longitude latitude
156 41.88367183 12.48777756
187 41.92854333 12.46903667
297 41.89106861 12.49270456
89 41.79317669 12.43212196
79 41.90027472 12.46274618
... ... ...
The pseudocode is as follows. it aims to compute the distance between two IDs on the surface of the earth with longitude and latitude, and outputs the cumulative sum from any two IDs:
dlon = lon2 - lon1
dlat = lat2 - lat1
a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2
c = 2 * atan2( sqrt(a), sqrt(1-a) )
distance = 6371000 * c (where 6371000 is the radius of the Earth)
This code is as follows, but it runs too slow. how to speed and rewrite the code? Thank you.
stu<-read.table("stu.csv",header=T,sep=",");
## stu has 850,000 rows and 3 columns.
m<-nrow(stu);
distance<-0;
for (i in 1:(m-1))
{
for (j in (i+1))
{
dlon = stu[j,2] - stu[i,2];
dlat = stu[j,3] - stu[i,3];
a = (sin(dlat/2))^2 + cos(stu[i,3]) * cos(stu[j,3]) * (sin(dlon/2))^2;
c = 2 * atan2( sqrt(a), sqrt(1-a) );
distance <-distance+6371000 * c;
}
}
distance
For your case, if it is the cumulative distance, we can vectorize:
x <- read.table(text = "ID longitude latitude
156 41.88367183 12.48777756
187 41.92854333 12.46903667
297 41.89106861 12.49270456
89 41.79317669 12.43212196
79 41.90027472 12.46274618", header= TRUE)
x$laglon <- dplyr::lead(x$longitude, 1)
x$laglat <- dplyr::lead(x$latitude, 1)
distfunc <- function(long, lat, newlong, newlat){
dlon = newlong - long
dlat = newlat - lat
a = (sin(dlat/2))^2 + cos(lat) * cos(newlat) * (sin(dlon/2))^2
c = 2 * atan2( sqrt(a), sqrt(1-a) )
6371000 * c
}
distfunc(x$longitude, x$latitude, x$laglon, x$laglat)
308784.6 281639.6 730496.0 705004.2 NA
Take the cumsum of the output to get the total distance.
On a million rows, it takes around 0.4 secs on my system
What you're looking for is called "vectorizing a loop." See this related question.
The basic idea is that in a loop, the CPU has to finish processing the first cell before moving on to the second cell, unless it has some guarantee that how the first cell is processed won't effect the state for the second cell. But if it's a vector computation, that guarantee exists, and it can work on as many elements simultaneously as possible, leading to faster speed. (There are other reasons why this works better, but that's the basic motivation.)
See this introduction to apply in R for how to rewrite your code without the loop. (Much of the calculation you should be able to maintain as is.)

Calculate second point knowing the starting point and distance

using a Latitude and Longitude value (Point A), I am trying to calculate another Point B, X meters away bearing 0 radians from point A. Then display the point B Latitude and Longitude values.
Example (Pseudo code):
PointA_Lat = x.xxxx;
PointA_Lng = x.xxxx;
Distance = 3; //Meters
bearing = 0; //radians
new_PointB = PointA-Distance;
I was able to calculate the distance between two Points but what I want to find is the second point knowing the distance and bearing.
Preferably in PHP or Javascript.
Thank you
It seems you are measuring distance (R) in meters, and bearing (theta) counterclockwise from due east. And for your purposes (hundereds of meters), plane geometry should be accurate enough. In that case,
dx = R*cos(theta) ; theta measured counterclockwise from due east
dy = R*sin(theta) ; dx, dy same units as R
If theta is measured clockwise from due north (for example, compass bearings),
the calculation for dx and dy is slightly different:
dx = R*sin(theta) ; theta measured clockwise from due north
dy = R*cos(theta) ; dx, dy same units as R
In either case, the change in degrees longitude and latitude is:
delta_longitude = dx/(111320*cos(latitude)) ; dx, dy in meters
delta_latitude = dy/110540 ; result in degrees long/lat
The difference between the constants 110540 and 111320 is due to the earth's oblateness
(polar and equatorial circumferences are different).
Here's a worked example, using the parameters from a later question of yours:
Given a start location at longitude -87.62788 degrees, latitude 41.88592 degrees,
find the coordinates of the point 500 meters northwest from the start location.
If we're measuring angles counterclockwise from due east, "northwest" corresponds
to theta=135 degrees. R is 500 meters.
dx = R*cos(theta)
= 500 * cos(135 deg)
= -353.55 meters
dy = R*sin(theta)
= 500 * sin(135 deg)
= +353.55 meters
delta_longitude = dx/(111320*cos(latitude))
= -353.55/(111320*cos(41.88592 deg))
= -.004266 deg (approx -15.36 arcsec)
delta_latitude = dy/110540
= 353.55/110540
= .003198 deg (approx 11.51 arcsec)
Final longitude = start_longitude + delta_longitude
= -87.62788 - .004266
= -87.632146
Final latitude = start_latitude + delta_latitude
= 41.88592 + .003198
= 41.889118
It might help if you knew that 3600 seconds of arc is 1 degree (lat. or long.), that there are 1852 meters in a nautical mile, and a nautical mile is 1 second of arc. Of course you're depending on the distances being relatively short, otherwise you'd have to use spherical trigonometry.
Here is an updated version using Swift:
let location = CLLocation(latitude: 41.88592 as CLLocationDegrees, longitude: -87.62788 as CLLocationDegrees)
let distanceInMeter : Int = 500
let directionInDegrees : Int = 135
let lat = location.coordinate.latitude
let long = location.coordinate.longitude
let radDirection : CGFloat = Double(directionInDegrees).degreesToRadians
let dx = Double(distanceInMeter) * cos(Double(radDirection))
let dy = Double(distanceInMeter) * sin(Double(radDirection))
let radLat : CGFloat = Double(lat).degreesToRadians
let deltaLongitude = dx/(111320 * Double(cos(radLat)))
let deltaLatitude = dy/110540
let endLat = lat + deltaLatitude
let endLong = long + deltaLongitude
Using this extension:
extension Double {
var degreesToRadians : CGFloat {
return CGFloat(self) * CGFloat(M_PI) / 180.0
}
}
dx = sin(bearing)
dy = cos(bearing)
x = center.x + distdx;
y = center.y + distdy;

Resources