/** * Returns the point which is a fraction along the line between 0 and 1. * * @param Point $point * @param float $fraction between 0 and 1 * * @throw \InvalidArgumentException * @return Point */ public function getFractionAlongLineTo(Point $point, $fraction) { if ($fraction < 0 || $fraction > 1) { throw new \InvalidArgumentException('$fraction must be between 0 and 1'); } if (function_exists('fraction_along_gc_line') && Location::$useSpatialExtension) { $result = fraction_along_gc_line($this->jsonSerialize(), $point->jsonSerialize(), $fraction); return new self($result['coordinates']); } else { $distance = Location::haversine($this, $point); $lat1 = $this->latitudeToRad(); $lat2 = $point->latitudeToRad(); $lon1 = $this->longitudeToRad(); $lon2 = $point->longitudeToRad(); $a = sin((1 - $fraction) * $distance) / sin($distance); $b = sin($fraction * $distance) / sin($distance); $x = $a * cos($lat1) * cos($lon1) + $b * cos($lat2) * cos($lon2); $y = $a * cos($lat1) * sin($lon1) + $b * cos($lat2) * sin($lon2); $z = $a * sin($lat1) + $b * sin($lat2); $res_lat = atan2($z, sqrt(pow($x, 2) + pow($y, 2))); $res_long = atan2($y, $x); return new self(rad2deg($res_lat), rad2deg($res_long)); } }