You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

103 lines
4.2 KiB

// This file is available in electronic form at http://www.psa.es/sdg/sunpos.htm
#include "sunpos.h"
#include <math.h>
void sunpos(cTime udtTime,cLocation udtLocation, cSunCoordinates *udtSunCoordinates)
{
// Main variables
double dElapsedJulianDays;
double dDecimalHours;
double dEclipticLongitude;
double dEclipticObliquity;
double dRightAscension;
double dDeclination;
// Auxiliary variables
double dY;
double dX;
// Calculate difference in days between the current Julian Day
// and JD 2451545.0, which is noon 1 January 2000 Universal Time
{
double dJulianDate;
long int liAux1;
long int liAux2;
// Calculate time of the day in UT decimal hours
dDecimalHours = udtTime.dHours + (udtTime.dMinutes
+ udtTime.dSeconds / 60.0 ) / 60.0;
// Calculate current Julian Day
liAux1 =(udtTime.iMonth-14)/12;
liAux2=(1461*(udtTime.iYear + 4800 + liAux1))/4 + (367*(udtTime.iMonth
- 2-12*liAux1))/12- (3*((udtTime.iYear + 4900
+ liAux1)/100))/4+udtTime.iDay-32075;
dJulianDate=(double)(liAux2)-0.5+dDecimalHours/24.0;
// Calculate difference between current Julian Day and JD 2451545.0
dElapsedJulianDays = dJulianDate-2451545.0;
}
// Calculate ecliptic coordinates (ecliptic longitude and obliquity of the
// ecliptic in radians but without limiting the angle to be less than 2*Pi
// (i.e., the result may be greater than 2*Pi)
{
double dMeanLongitude;
double dMeanAnomaly;
double dOmega;
dOmega=2.1429-0.0010394594*dElapsedJulianDays;
dMeanLongitude = 4.8950630+ 0.017202791698*dElapsedJulianDays; // Radians
dMeanAnomaly = 6.2400600+ 0.0172019699*dElapsedJulianDays;
dEclipticLongitude = dMeanLongitude + 0.03341607*sin( dMeanAnomaly )
+ 0.00034894*sin( 2*dMeanAnomaly )-0.0001134
-0.0000203*sin(dOmega);
dEclipticObliquity = 0.4090928 - 6.2140e-9*dElapsedJulianDays
+0.0000396*cos(dOmega);
}
// Calculate celestial coordinates ( right ascension and declination ) in radians
// but without limiting the angle to be less than 2*Pi (i.e., the result may be
// greater than 2*Pi)
{
double dSin_EclipticLongitude;
dSin_EclipticLongitude= sin( dEclipticLongitude );
dY = cos( dEclipticObliquity ) * dSin_EclipticLongitude;
dX = cos( dEclipticLongitude );
dRightAscension = atan2( dY,dX );
if( dRightAscension < 0.0 ) dRightAscension = dRightAscension + twopi;
dDeclination = asin( sin( dEclipticObliquity )*dSin_EclipticLongitude );
}
// Calculate local coordinates ( azimuth and zenith angle ) in degrees
{
double dGreenwichMeanSiderealTime;
double dLocalMeanSiderealTime;
double dLatitudeInRadians;
double dHourAngle;
double dCos_Latitude;
double dSin_Latitude;
double dCos_HourAngle;
double dParallax;
dGreenwichMeanSiderealTime = 6.6974243242 +
0.0657098283*dElapsedJulianDays
+ dDecimalHours;
dLocalMeanSiderealTime = (dGreenwichMeanSiderealTime*15
+ udtLocation.dLongitude)*rad;
dHourAngle = dLocalMeanSiderealTime - dRightAscension;
dLatitudeInRadians = udtLocation.dLatitude*rad;
dCos_Latitude = cos( dLatitudeInRadians );
dSin_Latitude = sin( dLatitudeInRadians );
dCos_HourAngle= cos( dHourAngle );
udtSunCoordinates->dZenithAngle = (acos( dCos_Latitude*dCos_HourAngle
*cos(dDeclination) + sin( dDeclination )*dSin_Latitude));
dY = -sin( dHourAngle );
dX = tan( dDeclination )*dCos_Latitude - dSin_Latitude*dCos_HourAngle;
udtSunCoordinates->dAzimuth = atan2( dY, dX );
if ( udtSunCoordinates->dAzimuth < 0.0 )
udtSunCoordinates->dAzimuth = udtSunCoordinates->dAzimuth + twopi;
udtSunCoordinates->dAzimuth = udtSunCoordinates->dAzimuth/rad;
// Parallax Correction
dParallax=(dEarthMeanRadius/dAstronomicalUnit)
*sin(udtSunCoordinates->dZenithAngle);
udtSunCoordinates->dZenithAngle=(udtSunCoordinates->dZenithAngle
+ dParallax)/rad;
}
}