A subject of Cosmic Proportions

After posting our article about deriving the position of the Sun, a reader suggested that, the sun being just another star, the code could be generalized to give the position of any star. So we have done.

The most generalized function in this work computes the position, given HourAngle and Declination (in radians)...

#include <math.h>
#include <time.h>
#define RAD_TO_DEGREE 57.29577951308233

void AltAz(double HourAngle, double Declination, double * Azimuth, double * Altitude){
  extern long  __latitude;
  double Latitude =  __latitude / ( ONE_DEGREE * RAD_TO_DEGREE);          // latitude in radians

  double CosHourAngle = cos(HourAngle);
  double SinLatitude = sin(Latitude);
  double CosLatitude = cos(Latitude);

  *Azimuth = atan ( sin(HourAngle) / ( CosHourAngle * SinLatitude - tan(Declination ) * CosLatitude ) );
  *Altitude = asin( CosHourAngle * cos(Declination) * CosLatitude + sin(Declination) * SinLatitude );
This function uses the convention that elevation is the angle of the object above the closest horizon, while the azimuth is measured from a North to South line, being negative toward the East and positive to the west.

The StarPosition function takes as input the time, Right Ascension in hours, and Declination in degrees. It figures out the HourAngle, converts Declination to radians, and passes everything to AltAz()...

void StarPosition(time_t * point_in_time, double RA, double Decl, double * Azimuth, double * Altitude){

  // RA is in hours... convert to seconds
  long ra = RA * ONE_HOUR;

  // get HA in sidereal seconds
  long ha = lm_sidereal(point_in_time) - ra;

  // convert to radians
  double HourAngle = ha * M_PI / 43200.0;

  // pass control to AltAz()
  AltAz(HourAngle, Decl / RAD_TO_DEGREE, Azimuth, Altitude);

The accuracy is limited by the precision of the avr 'double', but is close to the correct values.

The SolarPosition functions' input is just the time. It can figure out everything else...

void SolarPosition(time_t * point_in_time, double * Azimuth, double * Altitude){

  time_t noon = solar_noon(point_in_time) % ONE_DAY;      // time of noon mod one day
  time_t tday = *point_in_time % ONE_DAY;                 // current time mod one day
  long r = tday - noon;                                   // offset from noon, -43200 to + 43200 seconds
  double HourAngle = r / 86400.0;                         // hour angle as percentage of full day
  HourAngle = HourAngle * 2.0 * M_PI;                     // hour angle in radians

  double Declination = solar_declination(point_in_time);  // declination in radians
  AltAz( HourAngle, Declination,  Azimuth,  Altitude );


Questions and comments can be sent to