Suppose I have an ordered array containing points (lat, lon)
describing a path, and I also have a point (lat, lon)
describing my current location.
How can I project the point onto the path (and place the point in the appropriate place in the array)?
What I tried is just simply by searching for the nearest two points and assume it's in the middle of them. It's a good guess, but sometimes fails.
What would be a good way of doing this?
I see it like this:
p0,p1
are path line segment endpointsp
is your positionq'
closest point on line in 3D cartessianq
is q'
corrected by spherical projectionSo:
compute perpendicular distance from point and line
q'=p0+(dot(p-p0,p1-p0)*(p1-p0)/(|p-p0|*|p1-p0|))
perpendicular_distance = |p-q'|
find segment with smallest perpendicular_distance
and use only it for the rest of bullets
compute q
If you use sphere instead of ellipsoid then you already know the radius if not then either compute the radius algebraically or use average:
r=0.5*(|p0-(0,0,0)|+|p1-(0,0,0)|)
assuming (0,0,0)
is Earth's center. You can also be more precise if you weight by position:
w=|q'-p0|/|p1-p0|
r=(1-w)*|p0-(0,0,0)|+w*|p1-(0,0,0)|
now just correct the position of q'
q=q'*r/|q'|
set vector q'
as q
with size r
if it is not obvious enough. Also |p0-(0,0,0)|=|p0|
obviously but I wanted to be sure you get how I got it ...
convert q
from Cartesian to spherical coordinates
[Notes]
|a|
is size of vector a
done like: |a|=sqrt(ax*ax+ay*ay+az*az)
dot(a,b)
is dot product of vectors a,b
done like: dot(a,b)=(a.b)=ax*bx+ay*by+az*bz
if your path is not too complex shaped then you can use binary search to find the closest segment.
For distance comparison you do not need the sqrt
...