Take the following function that I shamelessly stole from somewhere on google:
function distance($lat1, $lon1, $lat2, $lon2, $unit) {
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$miles = $dist * 60 * 1.1515;
$unit = strtoupper($unit);
if ($unit == "K") {
return ($miles * 1.609344);
} else if ($unit == "N") {
return ($miles * 0.8684);
} else {
return $miles;
}
}
Appears to work great. Then I tried comparing the same long / lat to each other, and the result is not 0…
I’m not sure if this is a crazy happening of PHP and the way it stores the number or perhaps the math itself? I found another function that was written differently and the same thing happens.
cpradio
January 14, 2013, 11:36pm
2
Can you provide samples?
Here is what I did:
// Lima 40.329796, -84.210205
// Columbus 39.968701, -83.001709
$distance1 = distance(40.329796, -84.210205, 40.329796, -84.210205, 'N');
$distance2 = distance(40.329796, -84.210205, 40.329796, -84.210205, 'N');
var_dump($distance1, $distance2); // float(0) float(0) is the output
// Lima 40.329796, -84.210205
// Columbus 39.968701, -83.001709
$distance1 = distance(40.329796, -84.210205, 39.968701, -83.001709, 'N');
$distance2 = distance(40.329796, -84.210205, 39.968701, -83.001709, 'N');
var_dump($distance1, $distance2); // float(59.505373431747) float(59.505373431747) is the output
Yes, that works great, try this:
echo distance ( 40.329796 , - 84.210205 , 40.329796 , - 84.210205 , ‘N’ );
I get an output of float(0) when I do a var_dump.
<?php
function distance($lat1, $lon1, $lat2, $lon2, $unit) {
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$miles = $dist * 60 * 1.1515;
$unit = strtoupper($unit);
if ($unit == "K") {
return ($miles * 1.609344);
} else if ($unit == "N") {
return ($miles * 0.8684);
} else {
return $miles;
}
}
// Lima 40.329796, -84.210205
// Columbus 39.968701, -83.001709
$distance1 = distance(40.329796, -84.210205, 39.968701, -83.001709, 'N');
$distance2 = distance(40.329796, -84.210205, 39.968701, -83.001709, 'N');
$distance3 = distance(40.329796, -84.210205, 40.329796, -84.210205,'N');
var_dump($distance1, $distance2, $distance3);
?>
That’s right, it was only on a few examples was I seeing this happen. I’ll try to find one of them.
The only thing i can think of is a rounding error in deg2rad? But… no, that should come up with the same number even if it rounds wrong…
Please do, as I’m interested in tracking that down. I imagine it is a floating point scenario or something with precision but without a sample that produces it, it is hard for me to verify that.
Simplifying the math;
$theta = 0;
cos(0) = 1;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
becomes
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2));
or, because $lat1 and $lat2 are the same;
$dist = sin(deg2rad($lat1))^2 + cos(deg2rad($lat1))^2
the values of deg2rad for the same value will be the same, so i’ma call it $x
$dist = sin($x)^2 + cos($x)^2
My geometry lessons tell me that sin(x)^2+cos(x)^2 = 1.
acos(1) = 0.
so $dist should = 0.
It was especially interesting because it would return the same incorrect response every time it occurred (5.xxxxxxxxxxxxxx) not sure of the decimals, but it was long and truncated as well.