SitePoint Sponsor

User Tag List

Results 1 to 9 of 9
  1. #1
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    63 Post(s)
    Tagged
    2 Thread(s)

    Calling math and php gurus

    Take the following function that I shamelessly stole from somewhere on google:

    Code 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;
        }
    }

    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.

  2. #2
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,069
    Mentioned
    152 Post(s)
    Tagged
    0 Thread(s)
    Can you provide samples?

    Here is what I did:
    PHP Code:
    // Lima 40.329796, -84.210205
    // Columbus 39.968701, -83.001709
    $distance1 distance(40.329796, -84.21020540.329796, -84.210205'N');
    $distance2 distance(40.329796, -84.21020540.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.21020539.968701, -83.001709'N');
    $distance2 distance(40.329796, -84.21020539.968701, -83.001709'N');
    var_dump($distance1$distance2); // float(59.505373431747) float(59.505373431747) is the output 
    Last edited by cpradio; Jan 14, 2013 at 17:40. Reason: Added my own testing.
    Be sure to congratulate Patche on earning July's Member of the Month
    Go ahead and blame me, I still won't lose any sleep over it
    My Blog | My Technical Notes

  3. #3
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    63 Post(s)
    Tagged
    2 Thread(s)
    Yes, that works great, try this:

    echo distance(40.329796, -84.210205, 40.329796, -84.210205,'N');

  4. #4
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,069
    Mentioned
    152 Post(s)
    Tagged
    0 Thread(s)
    I get an output of float(0) when I do a var_dump.
    PHP Code:
    <?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.21020539.968701, -83.001709'N');
    $distance2 distance(40.329796, -84.21020539.968701, -83.001709'N');
    $distance3 distance(40.329796, -84.21020540.329796, -84.210205,'N');
    var_dump($distance1$distance2$distance3);
    ?>
    Be sure to congratulate Patche on earning July's Member of the Month
    Go ahead and blame me, I still won't lose any sleep over it
    My Blog | My Technical Notes

  5. #5
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    63 Post(s)
    Tagged
    2 Thread(s)
    That's right, it was only on a few examples was I seeing this happen. I'll try to find one of them.

  6. #6
    Keeper of the SFL StarLion's Avatar
    Join Date
    Feb 2006
    Location
    Atlanta, GA, USA
    Posts
    3,748
    Mentioned
    69 Post(s)
    Tagged
    0 Thread(s)
    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...
    Never grow up. The instant you do, you lose all ability to imagine great things, for fear of reality crashing in.

  7. #7
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,069
    Mentioned
    152 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by K. Wolfe View Post
    That's right, it was only on a few examples was I seeing this happen. I'll try to find one of them.
    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.
    Be sure to congratulate Patche on earning July's Member of the Month
    Go ahead and blame me, I still won't lose any sleep over it
    My Blog | My Technical Notes

  8. #8
    Keeper of the SFL StarLion's Avatar
    Join Date
    Feb 2006
    Location
    Atlanta, GA, USA
    Posts
    3,748
    Mentioned
    69 Post(s)
    Tagged
    0 Thread(s)
    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.
    Never grow up. The instant you do, you lose all ability to imagine great things, for fear of reality crashing in.

  9. #9
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    63 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by cpradio View Post
    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.
    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.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •