Sun position
Sun position algorithm
|
75 #ifndef SPA_COMPARISONS
77 LOCAL const double c_kmps = 299792.458;
78 LOCAL const double f = 0.0033528197;
79 LOCAL const double ae_km = 6378.1366;
80 LOCAL const double omega_radps = 7.292115e-5;
81 LOCAL const double au_km = 1.49597871464e8;
84 LOCAL const double f = 1.0 - 0.99664719;
85 LOCAL const double ae_km = 6378.140;
86 LOCAL const double au_km = 1.4960039e8;
88 LOCAL const double c_kmps = 299792.458;
89 LOCAL const double omega_radps = 7.292115e-5;
92 LOCAL const double esq = f + f - f * f;
106 double longitude_deg,
206 double sinPhi, cosPhi;
209 double rhoCosPhiP_km;
219 geodLat_rad =
degToRad(geodLat_deg);
220 geodLong_rad =
degToRad(geodLong_deg);
223 createAzElBaseM(site);
230 sincos(geodLat_rad, &sinPhi, &cosPhi);
231 invC = sqrt(1.0 - esq * (sinPhi * sinPhi));
232 aeC_km = ae_km / invC;
233 Kc = sqrt(1.0 - esq * (2.0 - esq) * (sinPhi * sinPhi));
237 site->
rhoSin_au = aeC_km * esq * sinPhi * cosPhi / au_km;
238 site->
rhoCos_au = -(ae_km * invC + height_m / 1000.0) / au_km;
241 rhoCosPhiP_km = (aeC_km + height_m / 1000.0) * cosPhi;
242 site->
diurnalAberr = omega_radps * rhoCosPhiP_km / c_kmps;
284 REQUIRE(temperature_degC > -100.0);
286 t = 283.0 / (273.0 + temperature_degC);
287 p = pressure_hPa / 1010.0;
368 if (polar->correctionInUse) {
440 #ifndef SPA_COMPARISONS
443 #warning "Correction for diurnal aberration is not being applied"
466 / (e0_deg + 5.11)))))
475 dEl_rad = 0.000296706 / tan(topo->elevation_rad + 0.00313756
476 / (topo->elevation_rad + 0.0891863))
485 if (topo->
rectV.a[2] >= 0.268 * w) {
487 tanZd = w / topo->rectV.a[2];
488 dEl_rad = (2.8253e-4 * tanZd - 3.9948e-7 * tanZd * tanZd * tanZd)
493 dEl_rad = (8.3323e-3 + 3.1786e-2 * topo->elevation_rad
494 + 2.0746e-2 * topo->elevation_rad * topo->elevation_rad)
495 / (1 + 20.995 * topo->elevation_rad
496 + 160.31 * topo->elevation_rad * topo->elevation_rad)
513 double *hourAngle_rad,
514 double *declination_rad)
624 double sinLon, cosLon;
625 double sinLat, cosLat;
629 site->
azElBaseM.a[0][0] = -sinLat * cosLon;
630 site->
azElBaseM.a[0][1] = -sinLat * sinLon;
637 site->
azElBaseM.a[2][0] = cosLat * cosLon;
638 site->
azElBaseM.a[2][1] = cosLat * sinLon;
V3D_Matrix azElPolM
rotation matrix from TIRS to Az/El coords
double v3d_magVSq(const V3D_Vector *srcV)
Return the square of the magnitude of the specified vector.
V3D_Matrix * v3d_multMxM(V3D_Matrix *destM, const V3D_Matrix *srcM1, const V3D_Matrix *srcM2)
Multiply 3x3 matrix by 3x3 matrix to give a new 3x3 matrix, as per [destM] = [srcM1]*[srcM2].
general.h - definitions of general use to (standard) C programs
V3D_Vector * v3d_polarToRect(V3D_Vector *destV, double alpha_rad, double delta_rad)
Converts polar (curvilinear) coordinates to equivalent rectangular (Cartesian) coordinates.
#define REQUIRE(test_)
Check preconditions.
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...
double astLat_rad
Astronomical latitude of site (ϕA) (radian)
#define LOCAL
C has some very silly default behaviours.
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.
void v3d_rectToPolar(double *alpha_rad, double *delta_rad, const V3D_Vector *srcV)
Converts rectangular (Cartesian) coordinates to the equivalent polar (curvilinear) ones.
V3D_Matrix * azElM
points to either azElPolM or azElBaseM
#define REQUIRE_NOT_NULL(pointer_)
,
#define SFA
A very small number, used to avoid divide by 0 errors.
double geocRadius_km
Approx geocentric radius of site (≈ ae*ρ)(km)
V3D_Matrix haDecM
rotation matrix from Az/El to HA/Dec coords
double rhoSin_au
ae*ρ*sin(ϕ - ϕ′) geocentre-to-site x (AU)
double azimuth_rad
azimuth (radian)
#define DEG2RAD
degrees to radians
void sky_adjustSiteForPolarMotion(const Sky_PolarMot *polar, Sky_SiteProp *site)
Modify our azEl rotation matrix to incorporate a polar motion rotation matrix.
double timeZone_d
time zone offset from UTC (fraction of a day)
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 th...
instead-of-math.h - header to be included instead of math.h
double v3d_dotProductV(const V3D_Vector *srcV1, const V3D_Vector *srcV2)
Return the dot product of the two vectors: res = [srcV1] · [srcV2] or res = ||srcV1|| * ||srcV2|| * c...
static double degToRad(double angle_deg)
Returns angle_deg converted from degrees to radians.
This structure contains polar motion parameters and a rotation matrix.
void sky_setSiteTimeZone(double timeZone_h, Sky_SiteProp *site)
Set the time zone offset for this site.
double astLong_rad
Astronomical longitude of site (radian)
#define DEFINE_THIS_FILE
Leave DEFINE_THIS_FILE undefined.
void sky_setSiteTempPress(double temperature_degC, double pressure_hPa, Sky_SiteProp *site)
Set refraction coefficients based on atmospheric temperature and pressure at the site.
double rhoCos_au
-ae*ρ*cos(ϕ - ϕ′) geocentre-to-site z (AU)
sky.h - structures and routines for astronomical observing & tracking
V3D_Matrix * v3d_createRotationMatrix(V3D_Matrix *destM, V3D_AxisNames axis, double angle_rad)
Creates a matrix to rotate a coordinate system about an axis.
double elevation_rad
elevation (or altitude) (radian)
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 Ho...
double refracPT
Refraction correction: pressure & temperature.
static void sincos(double angle_rad, double *sinA, double *cosA)
Calculates sine and cosine of an angle.
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) ...
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().
V3D_Vector * v3d_multMxV(V3D_Vector *destV, const V3D_Matrix *srcM, const V3D_Vector *srcV)
Multiply 3x3 matrix by 3x1 vector to give a new 3x1 vector, as per equation [destV] = [srcM] * [srcV]...
V3D_Matrix azElBaseM
as above, but excluding polar motion correctn
static double radToDeg(double angle_rad)
Returns angle_rad converted from radians to degrees.
double diurnalAberr
Diurnal aberration: caused by earth rotation.
Coordinates of a celestial object in the horizon frame, in both rectangular and polar forms.
V3D_Vector rectV
unit vector in horizon coordinates