public static function computeOffsetOrigin($to, $distance,  $heading) {
        $heading = deg2rad($heading);
        $distance /= MathUtil::EARTH_RADIUS;
        // http://lists.maptools.org/pipermail/proj/2008-October/003939.html
        $n1 = cos($distance);
        $n2 = sin($distance) * cos($heading);
        $n3 = sin($distance) * sin($heading);
        $n4 = sin(rad2deg($to['lat']));
        // There are two solutions for b. b = n2 * n4 +/- sqrt(), one solution results
        // in the latitude outside the [-90, 90] range. We first try one solution and
        // back off to the other if we are outside that range.
        $n12 = $n1 * $n1;
        $discriminant = $n2 * $n2 * $n12 + $n12 * $n12 - $n12 * $n4 * $n4;
        if ($discriminant < 0) {
            // No real solution which would make sense in LatLng-space.
            return null;
        }
        $b = $n2 * $n4 + sqrt($discriminant);
        $b /= $n1 * $n1 + $n2 * $n2;
        $a = ($n4 - $n2 * $b) / $n1;
        $fromLatRadians = atan2($a, $b);
        if ($fromLatRadians < -M_PI / 2 || $fromLatRadians > M_PI / 2) {
            $b = $n2 * $n4 - sqrt($discriminant);
            $b /= $n1 * $n1 + $n2 * $n2;
            $fromLatRadians = atan2($a, $b);
        }
        if ($fromLatRadians < -M_PI / 2 || $fromLatRadians > M_PI / 2) {
            // No solution which would make sense in LatLng-space.
            return null;
        }
        $fromLngRadians = rad2deg($to['lng']) -
                atan2($n3, $n1 * cos($fromLatRadians) - $n2 * sin($fromLatRadians));
        return ['lat' => rad2deg($fromLatRadians), 'lng' => rad2deg($fromLngRadians)];
    }
public static function computeOffsetOrigin($to, $distance,  $heading) {
        $heading = deg2rad($heading);
        $distance /= MathUtil::EARTH_RADIUS;
        // http://lists.maptools.org/pipermail/proj/2008-October/003939.html
        $n1 = cos($distance);
        $n2 = sin($distance) * cos($heading);
        $n3 = sin($distance) * sin($heading);
        $n4 = sin(rad2deg($to['lat']));
        // There are two solutions for b. b = n2 * n4 +/- sqrt(), one solution results
        // in the latitude outside the [-90, 90] range. We first try one solution and
        // back off to the other if we are outside that range.
        $n12 = $n1 * $n1;
        $discriminant = $n2 * $n2 * $n12 + $n12 * $n12 - $n12 * $n4 * $n4;
        if ($discriminant < 0) {
            // No real solution which would make sense in LatLng-space.
            return null;
        }
        $b = $n2 * $n4 + sqrt($discriminant);
        $b /= $n1 * $n1 + $n2 * $n2;
        $a = ($n4 - $n2 * $b) / $n1;
        $fromLatRadians = atan2($a, $b);
        if ($fromLatRadians < -M_PI / 2 || $fromLatRadians > M_PI / 2) {
            $b = $n2 * $n4 - sqrt($discriminant);
            $b /= $n1 * $n1 + $n2 * $n2;
            $fromLatRadians = atan2($a, $b);
        }
        if ($fromLatRadians < -M_PI / 2 || $fromLatRadians > M_PI / 2) {
            // No solution which would make sense in LatLng-space.
            return null;
        }
        $fromLngRadians = rad2deg($to['lng']) -
                atan2($n3, $n1 * cos($fromLatRadians) - $n2 * sin($fromLatRadians));
        return ['lat' => rad2deg($fromLatRadians), 'lng' => rad2deg($fromLngRadians)];
    }
public static function computeOffsetOrigin ( $ to , $ distance , $ heading ) { $ heading = deg2rad ( $ heading ) ; $ distance /= MathUtil :: EARTH_RADIUS ; // http://lists.maptools.org/pipermail/proj/2008-October/003939.html $ n1 = cos ( $ distance ) ; $ n2 = sin ( $ distance ) * cos ( $ heading ) ; $ n3 = sin ( $ distance ) * sin ( $ heading ) ; $ n4 = sin ( rad2deg ( $ to [ 'lat' ] ) ) ; // There are two solutions for b. b = n2 * n4 +/- sqrt(), one solution results // in the latitude outside the [-90, 90] range. We first try one solution and // back off to the other if we are outside that range. $ n12 = $ n1 * $ n1 ; $ discriminant = $ n2 * $ n2 * $ n12 + $ n12 * $ n12 - $ n12 * $ n4 * $ n4 ; if ( $ discriminant < 0 ) { // No real solution which would make sense in LatLng-space. return null ; } $ b = $ n2 * $ n4 + sqrt ( $ discriminant ) ; $ b /= $ n1 * $ n1 + $ n2 * $ n2 ; $ a = ( $ n4 - $ n2 * $ b ) / $ n1 ; $ fromLatRadians = atan2 ( $ a , $ b ) ; if ( $ fromLatRadians < - M_PI / 2 || $ fromLatRadians > M_PI / 2 ) { $ b = $ n2 * $ n4 - sqrt ( $ discriminant ) ; $ b /= $ n1 * $ n1 + $ n2 * $ n2 ; $ fromLatRadians = atan2 ( $ a , $ b ) ; } if ( $ fromLatRadians < - M_PI / 2 || $ fromLatRadians > M_PI / 2 ) { // No solution which would make sense in LatLng-space. return null ; } $ fromLngRadians = rad2deg ( $ to [ 'lng' ] ) - atan2 ( $ n3 , $ n1 * cos ( $ fromLatRadians ) - $ n2 * sin ( $ fromLatRadians ) ) ; return [ 'lat' => rad2deg ( $ fromLatRadians ) , 'lng' => rad2deg ( $ fromLngRadians ) ] ; }
Returns the location of origin when provided with a LatLng destination,
meters travelled and original heading. Headings are expressed in degrees
clockwise from North. This function returns null when no solution is
available.
@param to       The destination LatLng.
@param distance The distance travelled, in meters.
@param heading  The heading in degrees clockwise from north.
Returns the location of origin when provided with a LatLng destination meters travelled and original heading . Headings are expressed in degrees clockwise from North . This function returns null when no solution is available .