If I have the coordinates of a point (lat lon) and the azimuth angle how can I calculate what points are at "the end' of a distance of 10 miles.
Ex. I am watching North , I know I am at a certain point ... At 10 miles apart what coordinates has that geo point ?
This site has a pretty good collection of formulae. For your case,
Let lon1,lat1 be the starting point, θ the azimuth angle (also often referred to as the "bearing") in radians,
d the distance traveled (km), and R the earth's radius (approx 6371 km). Then you can find
the final coordinates lon2, lat2 :
lat2 = asin(sin(lat1)*cos(d/R) + cos(lat1)*sin(d/R)*cos(θ))
lon2 = lon1 + atan2(sin(θ)*sin(d/R)*cos(lat1), cos(d/R)−sin(lat1)*sin(lat2))
Note: d/R represents an angle in radians corresponding to the arc length d.
θ is measured such that North=0 degrees, East=90 degrees, and so forth.
That doesn't make much sense. Let's take the first formula
lat2 = asin(sin(lat1)*cos(d/R) + cos(lat1)*sin(d/R)*cos(θ))
sin(lat1)*cos(d/R) -> as sin and cos will never be larger than 1, the largest result can be 1
cos(lat1)*sin(d/R)*cos(θ) -> same as above: the biggest possible result is 1
=> the result is that lat2 according to that formula can be 2 at most.
You need to also have a bearing to calculate this distance as well. For very short distances, great circle distance (the distance along the path of the earth) will be very close to cartesian distance, but the site provided by Jim Lewis' answer is a nice interactive site. This site also has a very extensive set of lat/lon formulas http://williams.best.vwh.net/avform.htm.
Related
I'm looking for the R function (or code) equivalent to the MATLAB function scxsc
This gives the Intersection points for pairs of small circles on a sphere.
The application is "a vessel is at bearing X1 and distance d1 from point 1 and bearing X2 and distance d2 from point 2. What is it's position in Lat, lon?"
I see plenty of examples for the intersection of great circles but not with small circles
I found the answer on https://gis.stackexchange.com/questions/48937/calculating-intersection-of-two-circles/273855#273855
NB I have a suspicion that in the two (unmodified) lines below ...
lat1 = rad2deg(atan2(point1[2] ,point1[1]))
lon1= rad2deg(asin(point1[3]))
and
lat2 = rad2deg(atan2(point2[2] ,point2[1]))
lon2 = rad2deg(asin(point2[3]))
... the lat and lon are inverted !
It worked much better for me with these changes!
I have a set of latitudes and longitudes , so this is the data for an animal as it moves in time. what i want to do is to calculate turning angle, that is by what angle it turns between every movement. so say i have point 1, point 2 and point 3 with latitude and longitude value corresponding to each point(animal moves from point 1 to point 2 to point 3 and so on) and i want to calculate the angle between these 3 points, point 2 being the middle point. what should i do? my OS is windows and i am using R for analysis.
so here is my sample data:
longitude latitude
36.89379547 0.290166977
36.89384037 0.290194109
36.88999724 0.286821044
36.88708721 0.288339411
36.88650313 0.29010232
36.88563203 0.289939416
36.88545224 0.290924863
they are in decimal degrees
Using the function trackAzimuth in maptools:
library(maptools)
trackAngle <- function(xy) {
angles <- abs(c(trackAzimuth(xy), 0) -
c(0, rev(trackAzimuth(xy[nrow(xy):1, ]))))
angles <- ifelse(angles > 180, 360 - angles, angles)
angles[is.na(angles)] <- 180
angles[-c(1, length(angles))]
}
The trackAzimuth function is a simple loop wrapper around gzAzimuth. See ?gzAzimuth for references on calculating directions on the sphere.
Using your data:
x <- read.table(text = "longitude latitude
36.89379547 0.290166977
36.89384037 0.290194109
36.88999724 0.286821044
36.88708721 0.288339411
36.88650313 0.29010232
36.88563203 0.289939416
36.88545224 0.290924863", header = TRUE)
trackAngle(as.matrix(x))
[1] 10.12946 111.17211 135.88514 97.73801 89.74684
EDIT: I had to remove first/last angles from the function, something I was doing after the fact with this function elsewhere. Should be right now. :)
Also, the packages adehabitatLT and argosfilter contain functions to calculate track directions and angles.
Your data points vary over only a small range. We can look at one small patch of Earth's surface and pretend it's flat, two dimensional. You have to figure out the scale of how many km, meters, miles, whatever your favorite unit is, corresponds to one degree of latitude, and for one degree of longitude. The latter depends on latitude - it'll be the same as the scale for latitude when near the equator, but if you are standing within arm's length of the north pole, one step will take you through fifty degrees. Set up x,y coordinates where x=0 is at longitude 36.88000, and y=0 is latitude 0.29000.
So, now you have a series of (x,y) points. Take the differences from each point to the next: P2-P1, P3-P2, etc. These could be called "displacement vectors" but other terms may be used in other fields than where i'm from. Call them V1, V2, etc. Use dot products and norms: dot(V1,V2) = magnitude(V1)*magnitude(V2)*cos(a) where a is the angle by which V2 deviates from the direction of V1. Repeat for V3 and V2, and so on.
R has all the tools to do this, but I don't know enough syntax of R to give examples.
I'm trying to write an algorithm that does the following.
Given a current position (in Azimuth and Inclination) and a target position (again in A, I) in what direction should I travel to travel over the shortest path. The return value could be something like a vector A = -1, I = +0.5, that I can then scale for step size/time.
The shortest path can be found by using a great circle, this is easy to visualize, but it's hard to implement like above because my coordinate system isn't continuous.
My coordinate system is as followed (imagine standing in front of the sphere)
The azimuth is 0 ~ pi when traveling along the equator along the front side, it's 0 ~ -pi when traveling along the equator along the rear side.
The inclination is 0~+pi when traveling from the top to the bottom of the sphere.
So given this non-continuous coordinate system, how do I create a decision function that says 'increase A' to travel over the shortest path?
You have a couple of alternatives. The first is to use a Haversine formulation. There is some Javascript source code here. It requires using more traditional lat / lon where the equator is at 0 latitude and the poles are at +/- π or +/- 90° latitude (depending on your units) and longitude is in the range [-180°, 180°) or [-π, π) again depending on your units. You can repeatedly find the midpoint until you have an approximate path that suites your needs. The azimuth / inclination vector would just be the difference in lat / lon between two adjacent points, though over time this will likely induce an error if you repeatedly apply those lat / lon deltas to the location of your agent.
Another approach that may work well for you is to transform your spherical coordinates of your starting and ending location to cartesian coordinates, call them points ub and ue for beginning and end points. The normal vector v of the great circle connecting the two points is the cross product of the two (i.e. v = ub x ue) and the angle θ is just the arccosine of the normalized inner product (ie. θ = cos-1( (ue ∙ ue) / (|ub||ue)). You can then use quaternion rotation and iterate from 0 to θ about the vector v to actually navigate the path. With this approach, the actual instantaneous vector at some point p along the path is just the p x v, or you can just approximate this by using the cartesian difference between two adjacent points along the path.
I have a Point on the surface of the earth which I am converting to a Vector from Earth Center.
I have a True North Heading in degrees describing the path the point will travel on the surface of the earth.
I need to calculate a Vector which is perpendicular to the plane created by the path of this point along the earths surface.
I have tried calculating an arbitrary point along the path using the method described here
and then taking the cross product of the two vectors however it does not seem to be quite accurate enough and seems like more overhead than is necessary.
This is related to my other post ray-polygon-intersection-point-on-the-surface-of-a-sphere.
I'm assuming you're trying to compute a vector lying in the plane of the path, not perpendicular to it (since you've already got one - namely the vector from the origin to your point).
You first need to compute vectors lying in that plane that point due north and due east. To do this, let's call P your point, O the origin, and N = (0, 0, R) is the point at the top of your sphere. Then
e = cross(N - P, P - O)
is a vector that points due east, and is tangent to the sphere because it's perpendicular to P - O, a radius of the sphere.
For similar reasons
n = cross(e, P - O)
will point due north, and will be tangent to the sphere.
Now normalize n and e, and you've got an orthonormal basis for the tangent space at your point. To find a vector in a direction theta (say, counterclockwise from the positive east axis, to simplify the math), just take a little of e and a little of n:
v = cos(theta) * e + sin(theta) * n
Here's my understanding of your problem:
You have a point on the Earth's surface, specified as latitude/longitude coordinates
The direction "true north" is the direction that a person at that point would travel to reach the (geographic) North Pole by the most direct possible route. That is, the "true north vector" is tangent to the Earth's surface at your chosen point and points directly north, parallel to a line of longitude.
The direction of the point's motion will be (initially) tangent to the Earth's surface at your chosen point.
You have an angle in degrees from true north which specifies the heading at which this point is going to move.
This angle is the angle between the "true north vector" and the direction of motion of the point.
You want to calculate a vector that is tangent to the Earth's surface at that point but perpendicular to the direction of motion of the point.
If I've understood all that correctly, you can do it as follows:
The "true north vector" at latitude lat, longitude lng is given by [-sin(lat) * cos(lng), -sin(lat) * sin(lng), cos(lat)]
A vector perpendicular to the "true north vector" which points along a line of latitude (to the east) is given by [-sin(lng), cos(lng), 0]
Since these two vectors identify the plane tangent to the Earth's surface, and the vector specifying the direction of motion of your point is also in that plane, your motion vector is a linear combination of the previous two: [
-(sin(lat) * cos(lng) * cos(th) + sin(lng) * sin(th))
-(sin(lat) * sin(lng) * cos(th) - cos(lng) * sin(th))
cos(lat) * cos(th)
] where th is your heading angle.
To find a vector perpendicular to that motion vector, you can just take the cross product of the radius vector (that is, the vector pointing from the center of the Earth to your point,[cos(lat) * cos(lng), cos(lat) * sin(lng), sin(lat)] with the motion vector. (That math would be messy, best to let the computer handle it)
You already have 2 vectors:
N = (0,0,1) points straight up from the origin.
P = (a,b,c) points from the origin to your point.
Calculate the unit vector to your point
U = P/|P|
Calculate a unit vector perpendicular to U and N
E = U X N
Calculate a unit vector perpendicular to U and E (this will be tangent to the sphere)
T = U X E
T could be pointing either North or South, so
if T.z < 0, multiply T by -1.
T now points due north, and is parallel to the plane tangent to the sphere at P.
You now have enough information to construct a rotation matrix (R), so you can rotate T around U. You can find how to make a matrix for rotation around any axis on wikipedia:
Using R, you can calculate a vector pointing in the direction of travel.
A = RT
A is the answer you are looking for.
Say you have n GPS coordinates how could you work out the central GPS point between them?
In case it helps anyone now or in the future, here's an algorithm that's valid even for points near the poles (if it's valid at all, i.e. if I haven't made a silly math mistake ;-):
Convert the latitude/longitude coordinates to 3D Cartesian coordinates:
x = cos(lat) * cos(lon)
y = cos(lat) * sin(lon)
z = sin(lat)
Compute the average of x, the average of y, and the average of z:
x_avg = sum(x) / count(x)
y_avg = sum(y) / count(y)
z_avg = sum(z) / count(z)
Convert that direction back to latitude and longitude:
lat_avg = arctan(z_avg / sqrt(x_avg ** 2 + y_avg ** 2))
lon_avg = arctan(y_avg / x_avg)
Depends on what you mean by the central GPS point. You could simply take the average of all the points, as suggested by Stephen - but keep in mind that GPS coordinates are not continuous - this will fail spectacularly around discontinuities such as the poles.
In most cases you'll need to convert to a coordinate system that doesn't have this issue.
You could also look at all the points bounded by it, calculated all the distances to each GPS point, and minimize the sum of the distances to all the GPS points. You'll need to look into great circle calculations for this.
Further, each GPS might have a higher or lower degree of uncertainty, you should take that into account and weight them accordingly.
What exactly are you trying to find out?
-Adam