I ran out of time writing the previous post.
A Google for 'distance point line' (without the quotes) brings up lots
of hits
http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html is
quite technical.
http://en.wikipedia.org/wiki/Tangent_lines_to_circles has a good
description of circles and tangents.
http://www.worsleyschool.net/science/files/linepoint/distance.html has
5 different methods.... wish I'd found this before I wrote my
code :rolleyes:
Method 5 is kind of a cookbook approach, and you would think it was
easiest. But this solution is for a line, NOT a line segment. So in
fact Method 4 is better.
The following doesn't match my code in my previous post, and I haven't
checked it at all. So take it all with a grain of salt, and test
thoroughly.
Following Method 4, then:
Step 1:
You already have 2 points A (x1, y1) and B (x2, y2) defining a line
segment so you don't need to do step 1.
Step 2:
By Pythagoras, the distance between two points is sqrt( (x1-x2)^2 +
(y1-y2)^2 )
But this applies to planar, Cartesian geometry, not latitude/longitude
coordinates. So here's a simple, ROUGH, way to calculate distances
between points specified as lat/lon -- it gives answers in nautical
miles.
This assumes a locally flat Earth... it takes straight lines, rather
than following the curve of the Earth, so it will always underestimate
a little. The further apart the points, the greater the error. But it
should work OK for short distances, say less than 300nm or so. It also
assumes a spherical Earth, so I guess it will overestimate the North/
South component of the distance.
1 degree of latitude = 60nm (near enough, assuming a spherical Earth)
As you said, the length of a degree of longitude varies depending on
the latitude... at the equator, it is 60nm (by definition); at the
poles, it is 0
So 1 degree of longitude = 60 * (90-abs(lat))/90 nm
So Pythagoras's formula for distances on the Earth ROUGHLY =
sqrt( ((x1-x2)*60*((90-abs(y1+y2)/2)/90))^2 + ((y1-y2)*60)^2 )
where (x1,y1) is the long/lat of one point, (x2, y2) is the other.
Note that I take the average of the two latitudes (y1+y2)/2 to
calculate the length of a degree of longitude.
I use abs() to indicate absolute value, sqrt() to indicate square
root, and ^2 to indicate squared. I'm sure PHP has a function for the
first two, probably a power() function or similar too???
You'll need to use this numerous times to calculate distances between
several points, so write it as a function in PHP.
Step 3: as per the web page, but note that this assumes that the
intercept lies between A & B -- you should check for an oblique
triangle by comparing s with a, b, and c. If s is less than any of
these, then the triangle is oblique, and the calculation s * (s- a) *
(s - b) * (s - c) would result in a negative number, which you then
couldn't calculate the square root of. If s = a or b or c then the
calculation will be 0, which also won't let you get the right answer.
But all is not lost... in either of these cases, the nearest point to
P will be one of the ends of the segment (either A or B)... simply
compare the distance AP against BP... the minimum of these will be the
distance from P to the line segment.
There's also a special case of A,B, & P being colinear, in this case
the calculation of s will also be 0. You need to check whether P lies
between A & B -- if it's between (just compare (say) the x coordinate
of P to that of A & B), then distance is 0, otherwise the distance is
the minimum of the distances AP and BP.
Step 4:
As per the web site.