![]() |
SolTrack
SolTrack is a simple, free, fast and accurate C routine to compute the position of the Sun
|
#include "stdio.h"
#include "math.h"
Go to the source code of this file.
Data Structures | |
struct | Time |
Date and time to compute the Sun's position for, in UT. More... | |
struct | Location |
Location to compute the Sun's position for. More... | |
struct | Position |
Position of the Sun. More... | |
struct | RiseSet |
Rise and set data for the Sun. More... | |
Macros | |
#define | PI 3.14159265358979323846 |
#define | TWO_PI 6.28318530717958647693 |
#define | MPI 3.14159265358979323846e6 |
#define | R2D 57.2957795130823208768 |
#define | R2H 3.81971863420548805845 |
Functions | |
void | SolTrack (struct Time time, struct Location location, struct Position *position, int useDegrees, int useNorthEqualsZero, int computeRefrEquatorial, int computeDistance) |
Main function to compute the position of the Sun. More... | |
double | computeJulianDay (int year, int month, int day, int hour, int minute, double second) |
Compute the Julian Day from the date and time. More... | |
void | computeLongitude (int computeDistance, struct Position *position) |
Compute the ecliptic longitude of the Sun for a given Julian Day. More... | |
void | convertEclipticToEquatorial (double longitude, double cosObliquity, double *rightAscension, double *declination) |
Convert ecliptic coordinates to equatorial coordinates. More... | |
void | convertEquatorialToHorizontal (struct Location location, struct Position *position) |
Convert equatorial to horizontal coordinates. More... | |
void | eq2horiz (double sinLat, double cosLat, double longitude, double rightAscension, double declination, double agst, double *azimuth, double *sinAlt) |
Convert equatorial coordinates to horizontal coordinates. More... | |
void | convertHorizontalToEquatorial (double sinLat, double cosLat, double azimuth, double altitude, double *hourAngle, double *declination) |
Convert (refraction-corrected) horizontal coordinates to equatorial coordinates. More... | |
void | setNorthToZero (double *azimuth, double *hourAngle, int computeRefrEquatorial) |
Convert the South=0 convention to North=0 convention for azimuth and hour angle. More... | |
void | convertRadiansToDegrees (double *longitude, double *rightAscension, double *declination, double *altitude, double *azimuthRefract, double *altitudeRefract, double *hourAngle, double *declinationRefract, int computeRefrEquatorial) |
Convert final results from radians to degrees. More... | |
double | STatan2 (double y, double x) |
My version of the atan2() function - ~39% faster than built-in (in terms of number of instructions) More... | |
void | SolTrack_RiseSet (struct Time time, struct Location location, struct Position *position, struct RiseSet *riseSet, double sa0, int useDegrees, int useNorthEqualsZero) |
Compute rise, transit and set times for the Sun, as well as their azimuths/altitude. More... | |
double | rev (double angle) |
Fold an angle to take a value between 0 and 2pi. More... | |
double | rev2 (double angle) |
Fold an angle to take a value between -pi and pi. More... | |
#define PI 3.14159265358979323846 |
Referenced by rev2(), setNorthToZero(), SolTrack_RiseSet(), and STatan2().
#define TWO_PI 6.28318530717958647693 |
Referenced by computeLongitude(), rev(), rev2(), and setNorthToZero().
#define R2D 57.2957795130823208768 |
Referenced by convertRadiansToDegrees(), SolTrack(), and SolTrack_RiseSet().
#define R2H 3.81971863420548805845 |
Referenced by SolTrack_RiseSet().
void SolTrack | ( | struct Time | time, |
struct Location | location, | ||
struct Position * | position, | ||
int | useDegrees, | ||
int | useNorthEqualsZero, | ||
int | computeRefrEquatorial, | ||
int | computeDistance | ||
) |
Main function to compute the position of the Sun.
[in] | time | Struct containing date and time to compute the position for, in UT |
[in,out] | location | Struct containing the geographic location to compute the position for |
[out] | position | Struct containing the position of the Sun in horizontal (and equatorial if desired) coordinates |
[in] | useDegrees | Use degrees for input and output angular variables, rather than radians |
[in] | useNorthEqualsZero | Use the definition where azimuth=0 denotes north, rather than south |
[in] | computeRefrEquatorial | Compute refraction correction for equatorial coordinates: 0-no, 1-yes |
[in] | computeDistance | Compute distance to the Sun (in AU): 0-no, 1-yes |
Example Usage:
References Position::altitude, Position::altitudeRefract, Position::azimuthRefract, computeJulianDay(), computeLongitude(), convertEclipticToEquatorial(), convertEquatorialToHorizontal(), convertHorizontalToEquatorial(), convertRadiansToDegrees(), Location::cosLat, Position::cosObliquity, Time::day, Position::declination, Position::declinationRefract, Time::hour, Position::hourAngleRefract, Position::julianDay, Location::latitude, Location::longitude, Position::longitude, Time::minute, Time::month, R2D, Position::rightAscension, Time::second, setNorthToZero(), Location::sinLat, Position::tJC, Position::tJC2, Position::tJD, and Time::year.
Referenced by SolTrack_RiseSet().
double computeJulianDay | ( | int | year, |
int | month, | ||
int | day, | ||
int | hour, | ||
int | minute, | ||
double | second | ||
) |
Compute the Julian Day from the date and time.
Gregorian calendar only (>~1582).
[in] | year | Year of date |
[in] | month | Month of date |
[in] | day | Day of date |
[in] | hour | Hour of time |
[in] | minute | Minute of time |
[in] | second | Second of time |
JulianDay | Julian day for the given date and time |
Referenced by SolTrack().
void computeLongitude | ( | int | computeDistance, |
struct Position * | position | ||
) |
Compute the ecliptic longitude of the Sun for a given Julian Day.
Also computes the obliquity of the ecliptic and nutation.
[in] | computeDistance | Compute distance to the Sun (in AU): 0-no, 1-yes |
[in,out] | position | Position of the Sun |
References Position::cosObliquity, Position::distance, Position::longitude, Position::nutationLon, Position::obliquity, Position::tJC, Position::tJC2, and TWO_PI.
Referenced by SolTrack().
void convertEclipticToEquatorial | ( | double | longitude, |
double | cosObliquity, | ||
double * | rightAscension, | ||
double * | declination | ||
) |
Convert ecliptic coordinates to equatorial coordinates.
This function assumes that the ecliptic latitude = 0.
[in] | longitude | Ecliptic longitude of the Sun (rad) |
[in] | cosObliquity | Cosine of the obliquity of the ecliptic |
[out] | rightAscension | Right ascension of the Sun (rad) |
[out] | declination | Declination of the Sun (rad) |
References STatan2().
Referenced by SolTrack().
Convert equatorial to horizontal coordinates.
Also corrects for parallax and atmospheric refraction.
[in] | location | Geographic location of the observer (rad) |
[in,out] | position | Position of the Sun (rad) |
References Position::agst, Position::altitude, Position::altitudeRefract, Position::azimuthRefract, Location::cosLat, Position::cosObliquity, Position::declination, eq2horiz(), Location::longitude, Position::nutationLon, Location::pressure, Position::rightAscension, Location::sinLat, Location::temperature, Position::tJC2, and Position::tJD.
Referenced by SolTrack().
void eq2horiz | ( | double | sinLat, |
double | cosLat, | ||
double | longitude, | ||
double | rightAscension, | ||
double | declination, | ||
double | agst, | ||
double * | azimuth, | ||
double * | sinAlt | ||
) |
Convert equatorial coordinates to horizontal coordinates.
[in] | sinLat | Sine of the geographic latitude of the observer |
[in] | cosLat | Cosine of the geographic latitude of the observer |
[in] | longitude | Geographic longitude of the observer (rad) |
[in] | rightAscension | Right ascension of the Sun (rad) |
[in] | declination | Declination of the Sun (rad) |
[in] | agst | Apparent Greenwich sidereal time (Greenwich mean sidereal time, corrected for the equation of the equinoxes) |
[out] | azimuth | Azimuth ("wind direction") of the Sun (rad; 0=South) |
[out] | sinAlt | Sine of the altitude of the Sun above the horizon |
References STatan2().
Referenced by convertEquatorialToHorizontal().
void convertHorizontalToEquatorial | ( | double | sinLat, |
double | cosLat, | ||
double | azimuth, | ||
double | altitude, | ||
double * | hourAngle, | ||
double * | declination | ||
) |
Convert (refraction-corrected) horizontal coordinates to equatorial coordinates.
[in] | sinLat | Sine of the geographic latitude of the observer |
[in] | cosLat | Cosine of the geographic latitude of the observer |
[in] | azimuth | Azimuth ("wind direction") of the Sun (rad; 0=South) |
[in] | altitude | Altitude of the Sun above the horizon (rad) |
[out] | hourAngle | Hour angle of the Sun (rad; 0=South) |
[out] | declination | Declination of the Sun (rad) |
References STatan2().
Referenced by SolTrack().
void setNorthToZero | ( | double * | azimuth, |
double * | hourAngle, | ||
int | computeRefrEquatorial | ||
) |
Convert the South=0 convention to North=0 convention for azimuth and hour angle.
South=0 is the default in celestial astronomy. This makes the angles compatible with the compass/wind directions.
[in,out] | azimuth | Azimuth ("wind direction") of the Sun (rad) |
[in,out] | hourAngle | Hour angle of the Sun (rad) |
[in] | computeRefrEquatorial | Compute refraction correction for equatorial coordinates |
Referenced by SolTrack().
void convertRadiansToDegrees | ( | double * | longitude, |
double * | rightAscension, | ||
double * | declination, | ||
double * | altitude, | ||
double * | azimuthRefract, | ||
double * | altitudeRefract, | ||
double * | hourAngle, | ||
double * | declinationRefract, | ||
int | computeRefrEquatorial | ||
) |
Convert final results from radians to degrees.
Not touching intermediate results.
[in,out] | longitude | Ecliptical longitude of the Sun (rad->deg) |
[in,out] | rightAscension | Right ascension of the Sun (rad->deg) |
[in,out] | declination | Declination of the Sun (rad->deg) |
[in,out] | altitude | Altitude of the Sun above the horizon (rad->deg) |
[in,out] | azimuthRefract | Azimuth ("wind direction") of the Sun (rad->deg), corrected for refraction |
[in,out] | altitudeRefract | Altitude of the Sun above the horizon (rad->deg), corrected for refraction |
[in,out] | hourAngle | Hour angle of the Sun (rad->deg) |
[in,out] | declinationRefract | Declination of the Sun (rad->deg), corrected for refraction |
[in] | computeRefrEquatorial | Compute refraction correction for equatorial coordinates |
References R2D.
Referenced by SolTrack().
double STatan2 | ( | double | y, |
double | x | ||
) |
My version of the atan2() function - ~39% faster than built-in (in terms of number of instructions)
[in] | y | Numerator of the fraction to compute the arctangent for |
[in] | x | Denominator of the fraction to compute the arctangent for |
atan2(y,x) = atan(y/x), where the result will be put in the correct quadrant
References PI.
Referenced by convertEclipticToEquatorial(), convertHorizontalToEquatorial(), and eq2horiz().
void SolTrack_RiseSet | ( | struct Time | time, |
struct Location | location, | ||
struct Position * | position, | ||
struct RiseSet * | riseSet, | ||
double | rsAlt, | ||
int | useDegrees, | ||
int | useNorthEqualsZero | ||
) |
Compute rise, transit and set times for the Sun, as well as their azimuths/altitude.
[in] | time | Struct containing date and time to compute the position for, in UT |
[in] | location | Struct containing the geographic location to compute the position for |
[out] | position | Struct containing the position of the Sun |
[out] | riseSet | Struct containing the Sun's rise, transit and set data |
[in] | rsAlt | Altitude to return rise/set data for (radians; 0. is actual rise/set). rsAlt>pi/2: compute transit only |
[in] | useDegrees | Use degrees for input and output angular variables, rather than radians |
[in] | useNorthEqualsZero | Use the definition where azimuth=0 denotes north, rather than south |
Example Usage:
References Position::agst, Time::day, Position::declination, Time::hour, Location::latitude, Location::longitude, Time::minute, Time::month, PI, R2D, R2H, rev(), rev2(), Position::rightAscension, RiseSet::riseAzimuth, RiseSet::riseTime, Time::second, RiseSet::setAzimuth, RiseSet::setTime, SolTrack(), RiseSet::transitAltitude, RiseSet::transitTime, and Time::year.
double rev | ( | double | angle | ) |
Fold an angle to take a value between 0 and 2pi.
[in] | angle | Angle to fold (radians) |
Referenced by SolTrack_RiseSet().
double rev2 | ( | double | angle | ) |
Fold an angle to take a value between -pi and pi.
[in] | angle | Angle to fold (radians) |
References MPI, PI, and TWO_PI.
Referenced by SolTrack_RiseSet().