/** * testCalculateDestinationForBearingAndDistanceReturnsExpectedValue * * @param LatLong $latLong The starting point. * @param float $bearing The initial bearing. * @param float $distance The distance in metres to travel. * @param LatLong $expected The expected destination. * * @dataProvider getLatLongWithInitialBearingDistanceAndDestination */ public function testCalculateDestinationForBearingAndDistanceReturnsExpectedValue(LatLong $latLong, $bearing, $distance, LatLong $expected) { $actual = $latLong->calculateDestinationForBearingAndDistance($bearing, $distance); $tolerance = 0.3; $this->assertEqualsWithinTolerance($expected->getLatitude(), $actual->getLatitude(), $tolerance); $this->assertEqualsWithinTolerance($expected->getLongitude(), $actual->getLongitude(), $tolerance); $this->assertEquals($latLong->getHeight(), $actual->getHeight()); // Height remains constant. $this->assertEquals($expected->getDatum(), $actual->getDatum()); }
/** * Calculate the initial bearing (forward azimuth) to follow from this point to arrive at the given destination. * * @param LatLong $destination The destination. * * @return float The bearing in decimal degrees. */ public function calculateInitialBearing(LatLong $destination) { $latRad = $this->getLatitudeRadians(); $destLatRad = $destination->getLatitudeRadians(); $diffLongRad = deg2rad($destination->getLongitude() - $this->getLongitude()); $x = cos($latRad) * sin($destLatRad) - sin($latRad) * cos($destLatRad) * cos($diffLongRad); $y = sin($diffLongRad) * cos($destLatRad); $bearing = atan2($y, $x); return fmod(rad2deg($bearing) + 360, 360); }