Skip to content

Latest commit

 

History

History
764 lines (539 loc) · 22.5 KB

README.md

File metadata and controls

764 lines (539 loc) · 22.5 KB

Table of Contents

  1. Introduction
  2. Installation
  3. Example data
  4. Angle Util
  5. Time of Interest
    1. Create TOI
    2. Julian Day, Centuries & Millennia
    3. GMST, GAST & Equation of Time
  6. Location
  7. Coordinate Systems (and transformations)
  8. Astronomical Objects
    1. Sun
      1. Position
      2. Distance to earth
      3. Sunrise, Sunset & Culmination
    2. Moon
      1. Position
      2. Distance to earth
      3. Moonrise, Moonset & Culmination
      4. Phases
    3. Planets
      1. Heliocentric position of a planet
      2. Geocentric position of a planet
      3. Rise, Set & Culmination
  9. Events
    1. Solar Eclipse
      1. Create a Solar Eclipse
      2. Type, Obscuration, Magnitude, Duration
      3. Contacts (C1, C2, MAX, C3, C4)
    2. Lunar Eclipse
  10. Other calculations
    1. Distance between two locations
    2. Nutatation of earth

Introduction

This library provides tools and methods for astronomical calculations. With this bundle it is possible to calculate the position of moon, sun and planets and several coordinate systems. For a higher accuracy, several corrections, like nutation and precision, were taken into account. It is also possible to calculate rise, set and culmination events for celestial objects. For a detailed see the table of contents.

Most of the calculations are based on Jean Meeus 'Astronomical Algorithms' book and the VSOP87 theory.

Installation

Use composer to install this package.

composer require andrmoel/astronomy-bundle

Example data

Some example calculations are provided inside the /examples folder of the project dir. Usage:

php examples/sun.php

Angle Util

The angle util provides helper methods to convert an angle into different formats.

Example 1: Convert decimal angle

$angleDec = 132.6029282;

$angle = AngleUtil::dec2angle($angleDec);
$time = AngleUtil::dec2time($angleDec);

The result of the calculation should be:
Angle: 132°36'10.542"
Time: 8h50m24.703s

Example 2: Convert time into decimal format

$time = '8h50m24.703s';

$angle = AngleUtil::time2dec($time);

The result of the calculation should be:
Angle: 132.60292916667°

Time of Interest

The TimeOfInterest (TOI) object represents the time for which all of the astronomical calculations are done. For that reason it is the most important object in this library.

ℹ️ Why can't we simply use PHP's DateTime object?

The problem with PHP's own DateTime object is, that its supported range is '1000-01-01' to '9999-12-31'. So we cannot process calculations for dates before year 1000.

Create the TimeOfInterest object

There are several ways how to initialize the TOi object.

Example 1: Initialize the TimeOfInterest object for the date 02 July 2017 at 15:30:00 UTC

// Create from time
$toi = TimeOfInterest::create(2017, 7, 2, 15, 30, 0);
$toi = TimeOfInterest::createFromTime(2017, 7, 2, 15, 30, 0);

// Create from string
$toi = TimeOfInterest::createFromString('2017-07-02 15:30:00');

// Create from PHPs DateTime object
$dateTime = new \DateTime('2017-07-02 15:30:00');
$toi = TimeOfInterest::createFromDateTime($dateTime);

// Create from Julian Day
$JD = 2457937.1458333;
$toi = TimeOfInterest::createFromJulianDay($JD);

// Create from Julian Centuries since J2000
$T = 0.17500741501255;
$toi = TimeOfInterest::createFromJulianCenturiesJ2000($T);

echo $toi;

The Result will be always: 2017-07-02 15:30:00

Example 2: Create the TOI object for the current date and time in UTC

$toi = TimeOfInterest::createFromCurrentTime();

echo $toi;

The TimeOfInterest provides some methods to modify the time:

  • public function setDateTime(\DateTime $dateTime): void
  • public function setString(string $dateTimeStr): void
  • public function setJulianDay(float $JD): void
  • public function setJulianCenturiesJ2000(float $T): void

Example 3: Create the TOI object for the current time and change the time to 2017-07-02 15:30:00 UTC

$toi = TimeOfInterest::createFromCurrentTime();

$toi->setString('2017-07-02 15:30:00');

echo $toi;

The Result will be always: 2017-07-02 12:00:00

Julian Day, Julian Centuries from J2000 and Julian Millennia from J2000

Example: Create TOI for 02 July 2017 at 13:37 UTC

$toi = TimeOfInterest::createFromString('2017-07-02 13:37:00');

$JD = $toi->getJulianDay();
$JD0 = $toi->getJulianDay0();
$T = $toi->getJulianCenturiesFromJ2000();
$t = $toi->getJulianMillenniaFromJ2000();

The result of the calculation should be:
Julian Day: 2457937.0673611
Julian Day 0: 2457936.5
Julian Centuries J2000: 0.1750052665602
Julian Millennia J2000: 0.01750052665602

Greenwich Mean Sidereal Time (GMST), Greenwich Apparent Sidereal Time (GAST) and Equation of Time

With the help of the TOI-Object it is possible to calculate the GMST, GAST and the equation in time (units of all values are degrees). The following example explains how to get these values for 20 December 1992 at 00:00 UTC.

$toi = TimeOfInterest::createFromString('1992-12-20 00:00:00');

$GMST = $toi->getGreenwichMeanSiderealTime();
$GAST = $toi->getGreenwichApparentSiderealTime();
$E = $toi->getEquationOfTime();

The result of the calculation should be:
GMST: 88.82536°
GAST: 88.829629°
Equation of Time: 0.619485°

You may convert this values into the more common angle format by using AngleUtil::dec2time($value). The result will be:
GMST: 5h55m18.086s
GAST: 5h55m19.111s
Equation of Time: 0h2m28.676s

Location

The location object represents the location of the observer on the earth's surface.

// Initialize Location object for Berlin
$location = Location::create(52.524, 13.411);

// Initialize Location with elevation (Mt. Everest)
$location = Location::create(27.98787, 86.92483, 8848);

Coordinate systems and transformations

The bundle provides the common astronomical coordinate systems for calculations.

  • Geocentric Ecliptical Spherical (latitude, longitude)
  • Geocentric Equatorial Spherical (rightAscension, declination)
  • Geocentric Equatorial Rectangular (X, Y, Z)
  • Heliocentric Ecliptical Spherical (latitude, longitude)
  • Heliocentric Ecliptical Rectangular (X, Y, Z)
  • Heliocentric Equatorial Rectangular (x, y, z)
  • Local Horizontal (azimuth, altitude)

Each class provides methods to transform one coordinate system into another.

Example 1: Convert Geocentric Equatorial Spherical Coordinates into Geocentric Ecliptical Spherical Coordinates

$T = -0.12727429842574; // Julian Centuries since J2000 (1987-04-10 19:21:00)
$rightAscension = 116.328942;
$declination = 28.026183;

$geoEquSphCoord = new GeocentricEquatorialSphericalCoordinates($rightAscension, $declination);
$geoEclSphCoord = $geoEquSphCoord->getGeocentricEclipticalSphericalCoordinates($T);

$lon = $geoEclSphCoord->getLongitude();
$lat = $geoEclSphCoord->getLatitude();

Example 2: Convert Geocentric Equatorial Spherical Coordinates to Local Horizontal Coordinates

$location = Location::create(38.921389, -77.065556); // Washington DC
$T = -0.12727429842574; // Julian Centuries since J2000 (1987-04-10 19:21:00)
$rightAscension = 347.3193375;
$declination = -6.719891667;

$geoEquSphCoord = new GeocentricEquatorialSphericalCoordinates($rightAscension, $declination);
$locHorCoord = $geoEquSphCoord->getLocalHorizontalCoordinates($location, $T);

$altitude = $locHorCoord->getAltitude();
$azimuth = $locHorCoord->getAzimuth();

Astronomical Objects

An astronomical object must be initialized with the TOI. If you don't pass the TOI in the constructor, the current time is chosen.

$toi = TimeOfInterest::createFromString('2017-07-02 12:00:00');

$moon = Moon::create($toi);

Sun

Position of the sun

Example 1: Calculate the position of the sun for 17 May 2019 at 17:50 UTC

$toi = TimeOfInterest::createFromString('2019-05-17 17:50');

$sun = Sun::create($toi);

$geoEclSphCoordinates = $sun->getGeocentricEclipticalSphericalCoordinates();
$lon = $geoEclSphCoordinates->getLongitude();
$lat = $geoEclSphCoordinates->getLatitude();

The result of the calculation should be:
Longitude: 56.544°
Latitude: 0.0001°

Example 2: Calculate azimuth and altitude of the sun observed in Berlin, Germany for 17 May 2019 at 17:50 UTC

$toi = TimeOfInterest::createFromString('2019-05-17 17:50');

$location = Location::create(52.524, 13.411); // Berlin

$sun = Sun::create($toi);

$locHorCoord = $sun->getLocalHorizontalCoordinates($location);
$azimuth = $locHorCoord->getAzimuth();
$altitude = $locHorCoord->getAltitude();

The result of the calculation should be:
Azimuth: 291.0°
Altitude: 8.49°

The result of the altitude is corrected by atmospheric refraction. To obtain the local horizontal coordinates without correction of refraction, pass false as second parameter:

$locHorCoord = $sun->getLocalHorizontalCoordinates($location, false);

Distance of the sun to earth

Example 1: The current distance of the sun in kilometers can be calculated as follow:

$sun = Sun::create();

$distance = $sun->getDistanceToEarth();

The result should be between 147.1 mio and 152.1 mio kilometers.

Example 2: Get the distance of the sun on 05 June 2017 at 20:50 UTC

$toi = TimeOfInterest::createFromString('2017-06-05 20:50');

$sun = Sun::create($toi);

$distance = $sun->getDistanceToEarth();

The result should be 151797703km.

Sunrise, sunset and upper culmination

Calculate sunrise, sunset and upper culmination of the sun on 17 May 2019 in Berlin:

$toi = TimeOfInterest::createFromString('2019-05-17');

$location = Location::create(52.524, 13.411); // Berlin

$sun = Sun::create($toi);

// Results are TimeOfInterest objects
$sunrise = $sun->getSunrise($location);
$sunset = $sun->getSunset($location);
$upperCulmination = $sun->getUpperCulmination($location);

The result of the calculation should be:
Sunrise: 03:08 UTC
Sunset: 18:59 UTC
Upper culmination: 13:03 UTC

Moon

Position of the moon

Example 1: Calculate the geocentric position of the moon for 12 April 1992 at 00:00 UTC.

$toi = TimeOfInterest::createFromString('1992-04-12 00:00:00');

$moon = Moon::create($toi);

$geoEquSphCoord = $moon->getGeocentricEquatorialSphericalCoordinates();
$rightAscension = $geoEquSphCoord->getRightAscension();
$declination = $geoEquSphCoord->getDeclination();

The result of the calculation should be:
Right ascension: 134.69°
Declination: 13.77°

Example 2: Calculate azimuth and altitude of the moon observed in Berlin, Germany for 20 May 2019 at 23:00 UTC

$toi = TimeOfInterest::createFromString('2019-05-20 23:00:00');

$location = Location::create(52.524, 13.411); // Berlin

$moon = Moon::create($toi);

$locHorCoord = $moon->getLocalHorizontalCoordinates($location);
$azimuth = $locHorCoord->getAzimuth();
$altitude = $locHorCoord->getAltitude();

The result of the calculation should be:
Azimuth: 153.3°
Altitude: 12.28°

The result of the altitude is corrected by atmospheric refraction. To obtain the local horizontal coordinates without correction of refraction, pass false as second parameter:

$locHorCoord = $moon->getLocalHorizontalCoordinates($location, false);

Distance of the moon to earth

Example 1: The current distance of the moon in kimometers can be calculated as follow:

$moon = Moon::create();

$distance = $moon->getDistanceToEarth();

The result should be between 363300km and 405500km.

Example 2: Get the distance of the moon on 05 June 2017 at 20:50 UTC

$toi = TimeOfInterest::createFromString('2017-06-05 20:50');

$moon = Moon::create($toi);

$distance = $moon->getDistanceToEarth();

The result should be 402970km.

Moonrise, moonset and upper culmination

  • #f03c15 ATTENTION: Feature not yet implemented

Phases of the moon

The following code sniped explains how to calculate all important parameters which belong to the moons phase for an specific date. In this example it is 13 May 2019 at 21:30 UTC.

$toi = TimeOfInterest::createFromString('2019-05-13 21:30:00');

$moon = Moon::create($toi);

$isWaxing = $moon->isWaxingMoon();
$illumination = $moon->getIlluminatedFraction();
$positionAngle = $moon->getPositionAngleOfMoonsBrightLimb();

The result of the calculation should be:
Is waxing moon: yes
Illumination: 0.709 (70.9%)
Position angle of bright limb: 293.54°

Planets

Like Sun and Moon-Objects, the Planets can be created by passing the TimeOfInterest. If no TimeOfInteressed is passed, the current date and time are used for further calculations.

Example: Create some planets

$toi = TimeOfInterest::createFromString('2018-06-03 19:00:00');

$mercury = Mercury::create();  // Time = now
$venus = Venus::create($toi); // Time = 2018-06-03 19:00:00
$earth = Earth::create($toi);
$mars = Mars::create($toi);
$jupiter = Jupiter::create($toi);
$saturn = Saturn::create($toi);
$uranus = Uranus::create($toi);
$neptune = Neptune::create($toi);

Heliocentric position of a planet

The calculations use the VSOP87 theory to obtain the heliocentric position of a planet.

Example: Calculate the heliocentric position of Venus for 20. December 1992 at 00:00 UTC.

$toi = TimeOfInterest::createFromString('1992-12-20 00:00:00');

$venus = Venus::create($toi);

$helEclSphCoord = $venus->getHeliocentricEclipticalSphericalCoordinates();
$lon = $helEclSphCoord->getLongitude();
$lat = $helEclSphCoord->getLatitude();
$r = $helEclSphCoord->getRadiusVector();

$helEclRecCoord = $venus->getHeliocentricEclipticalRectangularCoordinates();
$x = $helEclRecCoord->getX();
$y = $helEclRecCoord->getY();
$z = $helEclRecCoord->getZ();

The result of the calculation should be:
Longitude: 26.11412°
Latitude: -2.62063°
Radius vector: 0.72460
X: 0.64995327095595
Y: 0.31860745636351
Z: -0.033130385747949

Geocentric position of a planet

All solutions for the geocentric calculations give the apparent position of a planet. That means the position of the planet is corrected by light time and aberration.

Example 1: Calculate the apparent geocentric position of Venus on 25 October 2018 at 07:15 UTC

$toi = TimeOfInterest::createFromString('2018-10-25 07:15:00');

$venus = Venus::create($toi);

$geoEclSphCoords = $venus->getGeocentricEclipticalSphericalCoordinates();
$lon = $geoEclSphCoords->getLongitude();
$lat = $geoEclSphCoords->getLatitude();

$geoEclSphCoords = $venus->getGeocentricEquatorialSphericalCoordinates();
$rightAscension = $geoEclSphCoords->getRightAscension();
$declination = $geoEclSphCoords->getDeclination();

The result of the calculation should be:
Longitude: 213.898092° (213°53'53.131")
Latitude: -6.476359° (-6°28'34.891")
Right ascension: 209.340427° (13h57m21.702s)
Declination: -18.898191° (-18°53'53.487")

Example 2: Calculate the azimuth and altitude of Venus on 25 October 2018 at 07:15 UTC in Berlin

$location = Location::create(52.524, 13.411); // Berlin

$toi = TimeOfInterest::createFromString('2018-10-25 07:15:00');

$venus = Venus::create($toi);

$locHorCoords = $venus->getLocalHorizontalCoordinates($location);
$azimuth = $locHorCoords->getAzimuth();
$altitude = $locHorCoords->getAltitude();

The result of the calculation should be:
Azimuth: 130.202°
Altitude: 5.038°

The result of the altitude is corrected by atmospheric refraction. To obtain the local horizontal coordinates without correction of refraction, pass false as second parameter:

$locHorCoord = $venus->getLocalHorizontalCoordinates($location, false);

Rise, set and upper culmination

Calculate rise, set and upper culmination of Venus on 25 October 2018 at 07:15 UTC in Berlin:

$location = Location::create(52.524, 13.411); // Berlin

$toi = TimeOfInterest::createFromString('2018-10-25 07:15:00');

$venus = Venus::create($toi);

// Results are TimeOfInterest objects
$rise = $venus->getRise($location);
$set = $venus->getSet($location);
$upperCulmination = $venus->getUpperCulmination($location);

The result of the calculation should be:
Rise: 06:31 UTC
Set: 15:06 UTC
Upper culmination: 10:49 UTC

Events

Solar eclipse

Create a Solar Eclipse object

Example: Create a solar eclipse for 21 August 2017 for the location Madrads in Oregon (USA)

$location = Location::create(44.61040, -121.23848); // Madras, OR

$toi = TimeOfInterest::createFromString('2017-08-21'); // Date of the eclipse (UTC)

$solarEclipse = SolarEclipse::create($toi, $location);

Note: If the date of the eclipse is invalid, an exception will be thrown.

Eclipse type, Obscuration, Magnitude, Duration, etc.

To obtain the eclipse circumstances of the maximum eclipse for a given location, see the following examples.

The type of an eclipse (for the given location) is expressed in a string. But it is better to use the following constants: SolarEclipse:TYPE_NONE, SolarEclipse:TYPE_PARTIAL, SolarEclipse:TYPE_ANNULAR or SolarEclipse:TYPE_TOTAL.

Example 1: Local circumstances for the total solar eclipse of 21 August 2017 for Madras, OR

$location = Location::create(44.61040, -121.23848); // Madras, OR

$toi = TimeOfInterest::createFromString('2017-08-21'); // Date of the eclipse (UTC)

$solarEclipse = SolarEclipse::create($toi, $location);

$type = $solarEclipse->getEclipseType();
$duration = $solarEclipse->getEclipseDuration(); // in seconds
$durationTotality = $solarEclipse->getEclipseUmbraDuration(); // in seconds
$obscuration = $solarEclipse->getObscuration();
$magnitude = $solarEclipse->getMagnitude();
$moonSunRatio = $solarEclipse->getMoonSunRatio();

The result of the calculation should be:
Type: total
Duration of eclipse: 9257s
Duration of totality: 120s
Obscuration: 1 (100%)
Magnitude: 1.01
Moon-sun-ratio: 1.03

Example 2: Local circumstances for the partial solar eclipse of 20 March 2015 in Berlin

$location = Location::create(52.52, 13.405); // Berlin

$toi = TimeOfInterest::createFromString('2015-03-20'); // Date of the eclipse (UTC)

$solarEclipse = SolarEclipse::create($toi, $location);

$type = $solarEclipse->getEclipseType();
$duration = $solarEclipse->getEclipseDuration(); // in seconds
$durationTotality = $solarEclipse->getEclipseUmbraDuration(); // in seconds
$obscuration = $solarEclipse->getObscuration();
$magnitude = $solarEclipse->getMagnitude();
$moonSunRatio = $solarEclipse->getMoonSunRatio();

The result of the calculation should be:
Type: partial
Duration of eclipse: 8386s
Duration of totality: 0s
Obscuration: 0.74 (74%)
Magnitude: 0.79
Moon-sun-ratio: 1.05

Contacts (C1, C2, MAX, C3, C4)

It is possible to obtains the current circumstances for each contact type (C1, C2, MAX, C3 and X4) for an eclipse.

  • C1: First contact - Eclipse begins
  • C2: Second contact - Begin of totality or annularity
  • MAX: Maximum obscuration of eclipse
  • C3: Third content - End of totality or annularity
  • C4: Fourth contact - Eclipse ends
$location = Location::create(44.61040, -121.23848); // Madras, OR

$toi = TimeOfInterest::createFromString('2017-08-21'); // Date of the eclipse (UTC)

$solarEclipse = SolarEclipse::create($toi, $location);

$c1 = $solarEclipse->getCircumstancesC1();
$c2 = $solarEclipse->getCircumstancesC2();
$max = $solarEclipse->getCircumstancesMax();
$c3 = $solarEclipse->getCircumstancesC3();
$c4 = $solarEclipse->getCircumstancesC4();

Example: Obtain the exact time of the second contact (C2) and the position of the sun. The solar eclipse happens on 21 August 2017 in Madras, Oregon.

$location = Location::create(44.61040, -121.23848); // Madras, OR

$toi = TimeOfInterest::createFromString('2017-08-21'); // Date of the eclipse (UTC)

$solarEclipse = SolarEclipse::create($toi, $location);

$c2 = $solarEclipse->getCircumstancesC2();

// Get time for C2
$toiC2 = $solarEclipse->getTimeOfInterest($c2);

// Get local horizontal coordinates (azimuth, altitude) of C2
$locHorCoord = $c2->getLocalHorizontalCoordinates();
$azimuth = $locHorCoord->getAzimuth();
$altitude = $locHorCoord->getAltitude();

The result of the calculation for the second contact (C2) should be:
Time of Interest: 2017-06-21 17:19:24 UTC
Azimuth of sun: 118.9°
Altitude of sun: 41.4°

The result of the altitude is corrected by atmospheric refraction. To obtain the local horizontal coordinates without correction of refraction, pass false as parameter:

$locHorCoord = $c2->getLocalHorizontalCoordinates(false);

Lunar eclipse

  • #f03c15 ATTENTION: Feature not yet implemented

Other calculations

Distance between two locations

$location1 = Location::create(52.524, 13.411); // Berlin
$location2 = Location::create(40.697,-74.539); // New York

$distance = EarthCalc::getDistanceBetweenLocations($location1, $location2);

The result of the calculation should be 6436km.

Nutation of earth

$T = -0.127296372458;

$nutationLon = EarthCalc::getNutationInLongitude($T);
$nutationLon = AngleUtil::dec2angle($nutationLon);

$nutationObl = EarthCalc::getNutationInObliquity($T);
$nutationObl = AngleUtil::dec2angle($nutationObl);

The result of the calculation should be:
Nutation in longitude: -0°0'3.788"
Nutation in obliquity: 0°0'9.442"