private static function isOnSegmentGC($lat1, $lng1, $lat2, $lng2, $lat3, $lng3, $havTolerance) { $havDist13 = MathUtil::havDistance($lat1, $lat3, $lng1 - $lng3); if ($havDist13 <= $havTolerance) { return true; } $havDist23 = MathUtil::havDistance($lat2, $lat3, $lng2 - $lng3); if ($havDist23 <= $havTolerance) { return true; } $sinBearing = self::sinDeltaBearing($lat1, $lng1, $lat2, $lng2, $lat3, $lng3); $sinDist13 = MathUtil::sinFromHav($havDist13); $havCrossTrack = MathUtil::havFromSin($sinDist13 * $sinBearing); if ($havCrossTrack > $havTolerance) { return false; } $havDist12 = MathUtil::havDistance($lat1, $lat2, $lng1 - $lng2); $term = $havDist12 + $havCrossTrack * (1 - 2 * $havDist12); if ($havDist13 > $term || $havDist23 > $term) { return false; } if ($havDist12 < 0.74) { return true; } $cosCrossTrack = 1 - 2 * $havCrossTrack; $havAlongTrack13 = ($havDist13 - $havCrossTrack) / $cosCrossTrack; $havAlongTrack23 = ($havDist23 - $havCrossTrack) / $cosCrossTrack; $sinSumAlongTrack = MathUtil::sinSumFromHav($havAlongTrack13, $havAlongTrack23); return $sinSumAlongTrack > 0; // Compare with half-circle == PI using sign of sin(). }
/** * Returns distance on the unit sphere; the arguments are in radians. */ private static function distanceRadians($lat1, $lng1, $lat2, $lng2) { return MathUtil::arcHav(MathUtil::havDistance($lat1, $lat2, $lng1 - $lng2)); }