Sun position
Sun position algorithm
sky.h File Reference

sky.h - structures and routines for astronomical observing & tracking More...

Go to the source code of this file.

Data Structures

struct  Sky_TrueEquatorial
 Struct used for holding an object's coordinates in equatorial apparent or Intermediate coordinates. More...
 
struct  Sky_SiteHorizon
 Coordinates of a celestial object in the horizon frame, in both rectangular and polar forms. More...
 
struct  Sky_DeltaTs
 This structure contains relatively constant data, and is set up by one of the three functions sky_initTime(), sky_initTimeSimple() or sky_initTimeDetailed(). More...
 
struct  Sky_Times
 This structure contains the continuously varying time (and earth rotation) data, in various forms that we will find useful. More...
 
struct  Sky_PolarMot
 This structure contains polar motion parameters and a rotation matrix. More...
 
struct  Sky_SiteProp
 Site properties. More...
 

Functions

void sky_initTime (int deltaAT_s, double deltaUT_s, Sky_DeltaTs *d)
 This is one of three alternative routines for setting up the various delta time values for use in ongoing calculations. More...
 
void sky_initTimeSimple (Sky_DeltaTs *d)
 This is one of three alternative routines for setting up the various delta time values for use in ongoing calculations. More...
 
void sky_initTimeDetailed (double mjdUtc, double usnoMjdBase, double usnoCoeffC11, double usnoCoeffC12, int deltaAT_s, Sky_DeltaTs *d)
 This is one of three alternative routines for setting up the various delta time values for use in ongoing calculations. More...
 
double sky_calTimeToJ2kd (int year, int month, int day, int hour, int minute, double second, double tz_h)
 Return the number of days (and fraction of a day) since noon 2000 Jan 1 (UTC) of the given calendar date and time. More...
 
double sky_unixTimeToJ2kd (time_t unixTime)
 Convert a time in Unix system time format to days since 2000 Jan 1, noon UTC. More...
 
double sky_unixTimespecToJ2kd (struct timespec uTs)
 
double sky_calTimeToMjd (int year, int month, int day, int hour, int minute, double second, double tz_h)
 
double sky_unixTimeToMjd (time_t unixTime)
 
double sky_unixTimespecToMjd (struct timespec uTs)
 
void sky_updateTimes (double j2kUtc_d, const Sky_DeltaTs *d, Sky_Times *t)
 Convert the given "J2KD" in the UTC timescale to the other timescales, and pre-calculate some other quantities. More...
 
void sky_updateTimesFromMjd (double mjdUtc, const Sky_DeltaTs *d, Sky_Times *t)
 
void sky_setPolarMotion (double xPolar_as, double yPolar_as, double t_cy, Sky_PolarMot *polar)
 Update polar motion correction. More...
 
void sky_j2kdToCalTime (double j2k_d, int *year, int *month, int *day, int *hour, int *minute, double *second)
 This procedure converts the integral part of the date in "J2KD" form to a calendar date and the fractional part to hours, minutes and seconds. More...
 
void sky_mjdToCalTime (double mjd, int *year, int *month, int *day, int *hour, int *minute, double *second)
 
void sky_setSiteLocation (double latitude_deg, double longitude_deg, double height_m, Sky_SiteProp *site)
 Initialise the site structure by calculating those site-related values that do not change with time. More...
 
void sky_setSiteLoc2 (double astLat_deg, double astLong_deg, double geodLat_deg, double geodLong_deg, double height_m, Sky_SiteProp *site)
 Alternative initialisation function to sky_setSiteLocation(). More...
 
void sky_setSiteTempPress (double temperature_degC, double pressure_hPa, Sky_SiteProp *site)
 Set refraction coefficients based on atmospheric temperature and pressure at the site. More...
 
void sky_setSiteTimeZone (double timeZone_h, Sky_SiteProp *site)
 Set the time zone offset for this site. More...
 
void sky_setupSiteSurface (double azimuth_deg, double slope_deg, Sky_SiteHorizon *surface)
 Set the orientation and slope of a surface (such as a solar panel) for which you want to calculate the incidence angle of incoming radiation. More...
 
void sky_adjustSiteForPolarMotion (const Sky_PolarMot *polar, Sky_SiteProp *site)
 Modify our azEl rotation matrix to incorporate a polar motion rotation matrix. More...
 
void sky_siteTirsToTopo (const V3D_Vector *terInterV, double dist_au, const Sky_SiteProp *site, Sky_SiteHorizon *topo)
 Transform a coordinate vector from the Terrestrial Intermediate Reference System to topocentric Az/El coordinates for the observing site whose properties are described in parameter "site". More...
 
void sky_siteAzElToHaDec (const V3D_Vector *topoV, const Sky_SiteProp *site, double *hourAngle_rad, double *declination_rad)
 Take a topocentric position vector in Azimuth/Elevation frame and use it to calculate the observed Hour Angle and Declination. More...
 
double sky_siteIncidence_rad (const V3D_Vector *topoV, const V3D_Vector *surfaceV)
 Calculate the incidence angle of rays from the celestial object described by topoV (such as the sun) falling onto a surface described by surfaceV (such as a solar panel). More...
 

Detailed Description

sky.h - structures and routines for astronomical observing & tracking


Author
David Hoadley

This collection is in two parts:

  • time routines. Routines for handling the different timescales used in astronomy, and for calculating the rotational orientation of the Earth. The timescales involved are TT, UT1 and UTC (see Timescales, and converting between them). Also included here is a routine to set polar motion parameters.
  • site routines. Data that is specific to an observing site on the Earth, and routines to convert astronomical coordinates to site-specific (i.e. topocentric) coordinates at the site. More than one site may be supported simultaneously, if required.

The routines are designed to provide an efficient implementation of the necessary calculations. When combined with the routines in the skyfast.h and skyfast.c module, they enable accurate tracking with even a small processor.

Other modules required:

  • sun.h (and sun.c) if you want to track the Sun, using either the NREL Solar Position Algorithm, or a simplified approximate one.
  • moon.h (and moon.c) if you want to track the Moon, using the NREL Moon Position Algorithm
  • (future) a module for tracking other planets
  • (future) a module for tracking stars
  • skyio.h (and skyio.c) for input-output routines: conversions of angles to and from strings in sexagesimal (e.g. degrees, minutes and seconds) form; writing out a day number as a date & time.
  • vectors3d.h (and vectors3d.c) which implements the rectangular matrix and vector operations used by these algorithms,

You will need to separately include one of the following modules:

  • sky0.h (and sky0.c) for nutation routines and sidereal time routines suitable for tracking the Sun or the Moon using the NREL Solar Position Algorithm and Moon Position Algorithm
  • (future) sky1.h (and sky1.c) for IAU 1980 precession, nutation and sidereal time routines, suitable for tracking stars
  • (future) sky2.h (and sky2.c) for IAU 2000 precession, nutation and sidereal time routines, suitable for tracking stars

Definition in file sky.h.

Function Documentation

◆ sky_initTime()

void sky_initTime ( int  deltaAT_s,
double  deltaUT_s,
Sky_DeltaTs d 
)

This is one of three alternative routines for setting up the various delta time values for use in ongoing calculations.

(The other two are sky_initTimeDetailed() and sky_initTimeSimple()). For an explanation of these delta times, see Timescales, and converting between them.

Parameters
[in]deltaAT_s(= TAI - UTC). Cumulative number of leap seconds (seconds)
[in]deltaUT_s(= UT1 - UTC) (seconds). Valid range [-0.9,+0.9]
[out]dFields initialised as follows:
  • d->deltaUT_d initialised to deltaUT_s / 86400
  • d->deltaT_d initialised to (deltaAT_s + 32.184 - deltaUT_s) / 86400
  • d->deltaTT_d initialised to (deltaAT_s + 32.184) / 86400
When to call this function
Call at program startup time. Use this routine if you have opted for option 3A, 3B or 3D in the note at the bottom of this file (see Timescales, and converting between them). (Use sky_initTimeDetailed() if you have opted for option 3C.)

Examples
demo1_sun.c, demo2_sun_tracking.c, and demo3_moon.c.

Definition at line 96 of file sky-time.c.

◆ sky_initTimeSimple()

void sky_initTimeSimple ( Sky_DeltaTs d)

This is one of three alternative routines for setting up the various delta time values for use in ongoing calculations.

(The other two are sky_initTime() and sky_initTimeDetailed()). This function initialises the delta times with simnple default values. For an explanation of these delta times, see Timescales, and converting between them.

Parameters
[out]dFields initialised as follows:
  • d->deltaUT_d initialised to 0.0
  • d->deltaT_d initialised to (37 + 32.184) / 86400
  • d->deltaTT_d initialised to (37 + 32.184) / 86400
When to call this function
Call this function at program startup time. Use this routine if you don't need the high accuracy of sub-second time. But if you do need it, call sky_initTime() or sky_initTimeDetailed() instead.

Definition at line 181 of file sky-time.c.

◆ sky_initTimeDetailed()

void sky_initTimeDetailed ( double  mjdUtc,
double  usnoMjdBase,
double  usnoCoeffC11,
double  usnoCoeffC12,
int  deltaAT_s,
Sky_DeltaTs d 
)

This is one of three alternative routines for setting up the various delta time values for use in ongoing calculations.

(The other two are sky_initTime() and sky_initTimeSimple()). This routine uses a prediction formula to calculate the value of delta_UT, rather than having it specified directly. For an explanation of these delta times, see Timescales, and converting between them.

Parameters
[in]mjdUtcModified Julian Date (= JD - 2 400 000.5), UTC timescale
[in]usnoMjdBase,usnoCoeffC11,usnoCoeffC12US Naval Observatory prediction formula values. These three values are obtained from "Bulletin A" of the International Earth Rotation Service (IERS), updated at the IERS (& USNO) website from time to time (see Timescales, and converting between them)
[in]deltaAT_s(= TAI - UTC). Cumulative number of leap seconds (seconds)
[out]dFields initialised as follows:
  • d->deltaUT_d initialised using USNO prediction formula
  • d->deltaT_d initialised to (deltaAT_s + 32.184) / 86400 - d->deltaUT_d
  • d->deltaTT_d initialised to (deltaAT_s + 32.184) / 86400
When to call this function
Call this function at program startup time. Use this routine if you have opted for option 3C in the note at the bottom of this file (see Timescales, and converting between them). (Use sky_initTime() instead, if you have opted for option 3A, 3B or 3D.) If your program runs uninterrupted for many days, you may wish to call this function once per day with an updated value for mjdUtc.

Examples
demo4_multiple_sites.c.

Definition at line 134 of file sky-time.c.

◆ sky_calTimeToJ2kd()

double sky_calTimeToJ2kd ( int  year,
int  month,
int  day,
int  hour,
int  minute,
double  second,
double  tz_h 
)

Return the number of days (and fraction of a day) since noon 2000 Jan 1 (UTC) of the given calendar date and time.

This is one of three alternative routines that return a J2KD - the other two are sky_unixTimeToJ2kd() and sky_unixTimespecToJ2kd().

Returns
days since Julian date 2 451 545.0, UTC timescale
Parameters
[in]year,month,daycalendar date
[in]hourvalid range [0, 23]
[in]minutevalid range [0, 59]
[in]secondvalid range [0.0, 60.0)
[in]tz_htime zone offset (hours), positive for zones east of Greenwich (e.g. Australian time zones AEST = +10.0, ACST = +9.5, AEDT = +11.0; UTC = 0.0; USA time zones are negative)
When to call this routine
Call this (or one of the alternative routines) before each call to sky_updateTimes().

Definition at line 241 of file sky-time.c.

◆ sky_unixTimeToJ2kd()

double sky_unixTimeToJ2kd ( time_t  unixTime)

Convert a time in Unix system time format to days since 2000 Jan 1, noon UTC.

This is one of three alternative routines that return a J2KD - the other two are sky_calTimeToJ2kd() and sky_unixTimespecToJ2kd().

Returns
days since Julian Date 2 451 545.0, UTC timescale
Parameters
[in]unixTime- time in C standard time_t (or unix) format ((sort of) seconds since 1-Jan-1970 UTC)
Note
This routine has no better resolution than one second. Use routine sky_unixTimespecToMjd() or sky_calTimeToMjd() instead, if you need sub-second resolution.
When to call this routine
Call this (or one of the alternative routines) before each call to sky_updateTimes().

Examples
demo1_sun.c, demo2_sun_tracking.c, demo3_moon.c, and demo4_multiple_sites.c.

Definition at line 275 of file sky-time.c.

◆ sky_updateTimes()

void sky_updateTimes ( double  j2kUtc_d,
const Sky_DeltaTs d,
Sky_Times t 
)

Convert the given "J2KD" in the UTC timescale to the other timescales, and pre-calculate some other quantities.

Parameters
[in]j2kUtc_dDate in "J2KD" form - i.e. the number of days elapsed since 2000 Jan 1.5 (= JD - 2 451 545.0), UTC timescale, as returned by sky_calTimeToJ2kd(), sky_unixTimeToJ2kd() or sky_unixTimespecToJ2kd().
[in]dThe various delta T values as set by one of sky_initTime(), sky_initTimeDetailed() or sky_initTimeSimple()
[out]tAll fields are updated
Reference
Astronomical Almanac 2007, page B9 (for Earth Rotation Angle)
When to call this function
Call this routine before calling any routine that calculates a celestial position.

Examples
demo4_multiple_sites.c.

Definition at line 206 of file sky-time.c.

◆ sky_setPolarMotion()

void sky_setPolarMotion ( double  xPolar_as,
double  yPolar_as,
double  t_cy,
Sky_PolarMot polar 
)

Update polar motion correction.

Parameters
[in]xPolar_asPolar motion in x (arcseconds)
[in]yPolar_asPolar motion in y (arcseconds)
[in]t_cyJulian centuries since J2000.0, TT timescale
[out]polarPolar motion params and rotation matrix, calculated from R1(-y) * R2(-x) * R3(s')
Reference
Astronomical Almanac 2007, page B80
When to call this function
This routine needs to be called only when polar motion parameters change - which is no more frequently than once per day. This effect is so small that it can be ignored altogether with only a tiny loss of accuracy.
Note
Every time this routine is called, the routine sky_adjustSiteForPolarMotion() must be called for every site. (Typically this will be only one site.)

Definition at line 570 of file sky-time.c.

◆ sky_j2kdToCalTime()

void sky_j2kdToCalTime ( double  j2k_d,
int *  year,
int *  month,
int *  day,
int *  hour,
int *  minute,
double *  second 
)

This procedure converts the integral part of the date in "J2KD" form to a calendar date and the fractional part to hours, minutes and seconds.

If the returned date is from 1582-10-15 or later, it is a Gregorian calendar date. If the returned date is 1582-10-04 or earlier, it is a Julian calendar date.

Parameters
[in]j2k_dDays since J2000.0 (= Julian Date - 2 451 545.0) Valid range: j2k_d >= -2447065, otherwise incorrect results
[out]year,month,daycalendar date
[out]hour,minute,secondtime of day
Reference
The algorithm is based on a method of D A Hatcher, Quarterly Journal of the Royal Astronomical Society 1984, Vol 25, pp 53-55. It is valid for dates after JD = 4480 (7 April 4701 BC, Julian calendar).
Note
To obtain calendar date and time for any timezone other than UTC, add the time zone offset (in units of fraction of a day) to mjd before calling this routine. The timezone_d field of the site properties struct (type Sky_SiteProp) provides this value.
If second turns out to be within half a millisecond of the next round minute, this routine rounds time upwards.

Definition at line 321 of file sky-time.c.

◆ sky_setSiteLocation()

void sky_setSiteLocation ( double  latitude_deg,
double  longitude_deg,
double  height_m,
Sky_SiteProp site 
)

Initialise the site structure by calculating those site-related values that do not change with time.

Parameters
[in]latitude_degLatitude of site (ϕ) (degrees)
[in]longitude_degLongitude of site (degrees)
[in]height_mHeight above ellipsoid (e.g. GPS height) (metres)
[out]siteAll fields initialised

This is a simplified version of sky_setSiteLoc2(), which is good enough for most purposes.

This function calculates the quantities that will be used to convert geocentric coordinates to topocentric ones. This involves calculating the position of the site relative to the centre of the earth, and calculating constants that will be used for diurnal parallax and aberration corrections.

This is complicated by the fact that the earth is elliptical rather than perfectly spherical. See section K of The Astronomical Almanac (pages K11 & K12 in the 2007 edition) for details of the geometry. This function effectively calculates the Geocentric latitude (ϕ′) from the Geodetic latitude (ϕ), and then sin(ϕ - ϕ′) and cos(ϕ - ϕ′). But in practice, the sin and cos terms can be obtained without explicitly calculating ϕ′ itself, and that is done here.

The site->refracPT field is initialised assuming that the site pressure is 1010 hPa and the temperature is 10 °C. If other values are required, follow this call by a call to sky_setSiteTempPress().

The site->timezone_d field is initialised to 0, assuming that the site time zone is UTC. If another value is required, follow this call by a call to sky_setSiteTimeZone().

When to call this function
At program initialisation time only

Examples
demo1_sun.c, demo2_sun_tracking.c, demo3_moon.c, and demo4_multiple_sites.c.

Definition at line 105 of file sky-site.c.

◆ sky_setSiteLoc2()

void sky_setSiteLoc2 ( double  astLat_deg,
double  astLong_deg,
double  geodLat_deg,
double  geodLong_deg,
double  height_m,
Sky_SiteProp site 
)

Alternative initialisation function to sky_setSiteLocation().

It initialises the site structure, but it supports a distinction between Astronomical latitude & longitude and Geodetic latitude & longitude.

Parameters
[in]astLat_degAstronomical Latitude of site (ϕA) (degrees)
[in]astLong_degAstronomical Longitude of site (degrees)
[in]geodLat_degGeodetic Latitude of site (GPS latitude) (ϕ) (degrees)
[in]geodLong_degGeodetic Longitude of site (GPS longitude) (degrees)
[in]height_mHeight above ellipsoid (e.g. GPS height) (metres)
[out]siteAll fields initialised

This function calculates the same quantities as described for sky_setSiteLocation(). The only difference is that the site.azElBaseM rotation matrix is based on Astronomical latitude and latitude (instead of Geodetic).

Astronomical latitude and longitude are coordinates as determined by the local gravity vector and astronomical observation. Geodetic latitude and longitude are coordinates as measured by some geodetic system - e.g. a map reference, or GPS coordinates.

Note
Distinguishing between Astronomical lat & lon and Geodetic lat & lon is only required for very precise work. It is most likely that you won't actually know the Astronomical coords, and it won't matter. Use function sky_setSiteLocation() instead - it sets the Astronomical coords to the same values as the Geodetic or GPS coords.

The site->refracPT field is initialised assuming that the site pressure is 1010 hPa and the temperature is 10 °C. If other values are required, follow this call by a call to sky_setSiteTempPress().

The site->timezone_d field is initialised to 0, assuming that the site time zone is UTC. If another value is required, follow this call by a call to sky_setSiteTimeZone().

When to call this function
At program initialisation time only, if you need to distinguish between Astronomical latitude/longitude and Geodetic latitude/longitude. Otherwise call sky_setSiteLocation() instead.

Definition at line 156 of file sky-site.c.

◆ sky_setSiteTempPress()

void sky_setSiteTempPress ( double  temperature_degC,
double  pressure_hPa,
Sky_SiteProp site 
)

Set refraction coefficients based on atmospheric temperature and pressure at the site.

Parameters
[in]temperature_degC- average annual air temperature at the site (°C)
[in]pressure_hPa- average annual air pressure at the site (hPa = mbar)
[out]site- field refracPT, a combined refraction coefficient for pressure & temperature

This coefficient will be used in the simple refraction algorithm that is called from routine sky_siteTirsToTopo().

When to call this function
  1. At program initialisation time, after calling sky_setSiteLocation() (or sky_setSiteLoc2())
  2. If you have updated values of pressure or temperature

Examples
demo1_sun.c, demo2_sun_tracking.c, demo3_moon.c, and demo4_multiple_sites.c.

Definition at line 261 of file sky-site.c.

◆ sky_setSiteTimeZone()

void sky_setSiteTimeZone ( double  timeZone_h,
Sky_SiteProp site 
)

Set the time zone offset for this site.

Parameters
[in]timeZone_hZonal correction (hours). Time zones east of Greenwich are positive (e.g. Australian Eastern Standard Time is +10.0) and those west of Greenwich are negative (e.g. US Pacific Daylight Time is -7.0)
[out]sitefield timeZone_d, time zone scaled to fractions of a day
When to call this function
  1. At program initialisation time, after calling sky_setSiteLocation() (or sky_setSiteLoc2())
  2. If daylight saving begins or ends during the time the program is running

Examples
demo1_sun.c, demo2_sun_tracking.c, demo3_moon.c, and demo4_multiple_sites.c.

Definition at line 293 of file sky-site.c.

◆ sky_setupSiteSurface()

void sky_setupSiteSurface ( double  azimuth_deg,
double  slope_deg,
Sky_SiteHorizon surface 
)

Set the orientation and slope of a surface (such as a solar panel) for which you want to calculate the incidence angle of incoming radiation.

Parameters
[in]azimuth_degThe azimuth angle of the normal to the surface (degrees). This is measured clockwise from North, as for all other azimuth angles.
[in]slope_degThe slope of the surface measured from the horizontal (degrees). Alternatively, this is the zenith distance of the normal to the surface.
[out]surfaceThe coordinates of the normal to the surface, in both polar and rectangular forms. The rectangular form will be passed later to sky_siteIncidence_rad().
When to call this function
At program initialisation time only, if you have a surface of interest.

Definition at line 317 of file sky-site.c.

◆ sky_adjustSiteForPolarMotion()

void sky_adjustSiteForPolarMotion ( const Sky_PolarMot polar,
Sky_SiteProp site 
)

Modify our azEl rotation matrix to incorporate a polar motion rotation matrix.

Parameters
[in]polarPolar motion parameters, as set by function sky_setPolarMotion()
[in,out]siteFields azElM and possibly azElPolM are updated
When to call this function
Polar motion is such a tiny effect that you may well decide not to bother with it. So you only need to call this routine if:
  1. you are bothering about polar motion at all, and
  2. changes were made to the polar structure by a recent call to function sky_setPolarMotion(). This routine is only ever to be called after that routine has run. This is expected to be very infrequently - once per day is more than enough.

Definition at line 347 of file sky-site.c.

◆ sky_siteTirsToTopo()

void sky_siteTirsToTopo ( const V3D_Vector terInterV,
double  dist_au,
const Sky_SiteProp site,
Sky_SiteHorizon topo 
)

Transform a coordinate vector from the Terrestrial Intermediate Reference System to topocentric Az/El coordinates for the observing site whose properties are described in parameter "site".

Note: there is a mixture of vectors in right-handed and left-handed coordinate systems here

Parameters
[in]terInterVPosition vector in Terrestrial Intermediate Reference System. (This will have been obtained by calling either routine astsite_appToTirs() or routine astsite_intermedToTopo().)
[in]dist_auGeocentric Distance to object (astronomical units). Note: for far distant objects outside of the solar system, you can supply 0.0 for this value. It will be treated as infinity.
[in]siteBlock of data describing the observing site, as initialised by one of the functions sky_setSiteLocation() or sky_setSiteLoc2().
[out]topoTopocentric position, both as a vector in horizon coordinates, and as azimuth (radian) and elevation (radian).
When to call this function
When you have the position of a celestial object expressed in the Terrestrial Intermediate Reference System, use this function to convert it to topocentric coordinates (the coordinates as seen from a particular observing location on the Earth's surface). If you are running a control loop to enable continuous tracking of this object, you will need to call this function every time around your control loop.
If you wish to calculate the position of the object as seen from multiple sites simultaneously, you need to call this function once for each of those sites, passing the relevant site data block to each call.

Examples
demo4_multiple_sites.c.

Definition at line 378 of file sky-site.c.

◆ sky_siteAzElToHaDec()

void sky_siteAzElToHaDec ( const V3D_Vector topoV,
const Sky_SiteProp site,
double *  hourAngle_rad,
double *  declination_rad 
)

Take a topocentric position vector in Azimuth/Elevation frame and use it to calculate the observed Hour Angle and Declination.

Parameters
[in]topoVTopocentric position vector in Azimuth/Elevation frame (as returned by the sky_siteTirsToTopo() function)
[in]siteField haDecM - rotation matrix to HA/Dec coordinates
[out]hourAngle_radHour angle (radian - note: not in hours)
[out]declination_radDeclination (radian)

The hour angle and declination returned by this function will be those of the refracted position of the object.

When to call this function
After each call to sky_siteTirsToTopo(), but only if you want hour angle and declination.

Definition at line 511 of file sky-site.c.

◆ sky_siteIncidence_rad()

double sky_siteIncidence_rad ( const V3D_Vector topoV,
const V3D_Vector surfaceV 
)

Calculate the incidence angle of rays from the celestial object described by topoV (such as the sun) falling onto a surface described by surfaceV (such as a solar panel).

Returns
Incidence angle of the radiation (radian)
Parameters
[in]topoVUnit vector pointing to the celestial object, as returned by the sky_siteTirsToTopo() routine (in the topo->rectV field). Must be of unity magnitude, otherwise an assertion failure occurs.
[in]surfaceVUnit vector of normal to the surface, as returned by routine sky_setupSiteSurface() (in the surface->rectV field). Must be of unity magnitude, otherwise an assertion failure occurs.
When to call this function
After each call to sky_siteTirsToTopo(), but only if you have a surface that you want the incidence angle for.

Definition at line 547 of file sky-site.c.