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