Eatdirt: Implement parallax effects for the Moon at the rendering stage and not with the ephemeris.
This commit is contained in:
parent
60f5df2998
commit
62501e5ede
@ -68,7 +68,8 @@ SGEphemeris::~SGEphemeris( void ) {
|
|||||||
void SGEphemeris::update( double mjd, double lst, double lat ) {
|
void SGEphemeris::update( double mjd, double lst, double lat ) {
|
||||||
// update object positions
|
// update object positions
|
||||||
our_sun->updatePosition( mjd );
|
our_sun->updatePosition( mjd );
|
||||||
moon->updatePosition( mjd, lst, lat, our_sun );
|
// moon->updatePositionTopo( mjd, lst, lat, our_sun );
|
||||||
|
moon->updatePosition( mjd, our_sun );
|
||||||
mercury->updatePosition( mjd, our_sun );
|
mercury->updatePosition( mjd, our_sun );
|
||||||
venus->updatePosition( mjd, our_sun );
|
venus->updatePosition( mjd, our_sun );
|
||||||
mars->updatePosition( mjd, our_sun );
|
mars->updatePosition( mjd, our_sun );
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
* Written by Durk Talsma <d.talsma@direct.a2000.nl> and Curtis Olson
|
* Written by Durk Talsma <d.talsma@direct.a2000.nl> and Curtis Olson
|
||||||
* <http://www.flightgear.org/~curt>
|
* <http://www.flightgear.org/~curt>
|
||||||
*
|
*
|
||||||
* Introduction
|
* Introduction
|
||||||
*
|
*
|
||||||
* The SGEphemeris class computes and stores the positions of the Sun,
|
* The SGEphemeris class computes and stores the positions of the Sun,
|
||||||
* the Moon, the planets, and the brightest stars. These positions
|
* the Moon, the planets, and the brightest stars. These positions
|
||||||
@ -146,6 +146,11 @@ public:
|
|||||||
return moon->getDeclination();
|
return moon->getDeclination();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return the geocentric distance to the Moon in unit of its semi-mayor axis. */
|
||||||
|
inline double getMoonDistanceInMayorAxis() const {
|
||||||
|
return moon->getDistanceInMayorAxis();
|
||||||
|
}
|
||||||
|
|
||||||
/** @return the numbers of defined planets. */
|
/** @return the numbers of defined planets. */
|
||||||
inline int getNumPlanets() const { return nplanets; }
|
inline int getNumPlanets() const { return nplanets; }
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* moonpos.cxx
|
* moonpos.cxx
|
||||||
* Written by Durk Talsma. Originally started October 1997, for distribution
|
* Written by Durk Talsma. Originally started October 1997, for distribution
|
||||||
* with the FlightGear project. Version 2 was written in August and
|
* with the FlightGear project. Version 2 was written in August and
|
||||||
* September 1998. This code is based upon algorithms and data kindly
|
* September 1998. This code is based upon algorithms and data kindly
|
||||||
* provided by Mr. Paul Schlyter. (pausch@saaf.se).
|
* provided by Mr. Paul Schlyter. (pausch@saaf.se).
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
@ -37,10 +37,10 @@
|
|||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* MoonPos::MoonPos(double mjd)
|
* MoonPos::MoonPos(double mjd)
|
||||||
* Public constructor for class MoonPos. Initializes the orbital elements and
|
* Public constructor for class MoonPos. Initializes the orbital elements and
|
||||||
* sets up the moon texture.
|
* sets up the moon texture.
|
||||||
* Argument: The current time.
|
* Argument: The current time.
|
||||||
* the hard coded orbital elements for MoonPos are passed to
|
* the hard coded orbital elements for MoonPos are passed to
|
||||||
* CelestialBody::CelestialBody();
|
* CelestialBody::CelestialBody();
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
MoonPos::MoonPos(double mjd) :
|
MoonPos::MoonPos(double mjd) :
|
||||||
@ -70,21 +70,23 @@ MoonPos::~MoonPos()
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* void MoonPos::updatePosition(double mjd, Star *ourSun)
|
* void MoonPos::updatePositionTopo(double mjd, double lst, double
|
||||||
* this member function calculates the actual topocentric position (i.e.)
|
* lat, Star *ourSun) this member function calculates the actual
|
||||||
* the position of the moon as seen from the current position on the surface
|
* topocentric position (i.e.) the position of the moon as seen from
|
||||||
* of the moon.
|
* the current position on the surface of the earth. This include
|
||||||
|
* parallax effects, the moon appears on different stars background
|
||||||
|
* for different observers on the surface of the earth.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
void MoonPos::updatePositionTopo(double mjd, double lst, double lat, Star *ourSun)
|
||||||
{
|
{
|
||||||
double
|
double
|
||||||
eccAnom, ecl, actTime,
|
eccAnom, ecl, actTime,
|
||||||
xv, yv, v, r, xh, yh, zh, zg, xe,
|
xv, yv, v, r, xh, yh, zh, zg, xe,
|
||||||
Ls, Lm, D, F, mpar, gclat, rho, HA, g,
|
Ls, Lm, D, F, mpar, gclat, rho, HA, g,
|
||||||
geoRa, geoDec,
|
geoRa, geoDec,
|
||||||
cosN, sinN, cosvw, sinvw, sinvw_cosi, cosecl, sinecl, rcoslatEcl,
|
cosN, sinN, cosvw, sinvw, sinvw_cosi, cosecl, sinecl, rcoslatEcl,
|
||||||
FlesstwoD, MlesstwoD, twoD, twoM, twolat, alpha;
|
FlesstwoD, MlesstwoD, twoD, twoM, twolat, alpha;
|
||||||
|
|
||||||
double max_loglux = -0.504030345621;
|
double max_loglux = -0.504030345621;
|
||||||
double min_loglux = -4.39964634562;
|
double min_loglux = -4.39964634562;
|
||||||
double conv = 1.0319696543787917; // The log foot-candle to log lux conversion factor.
|
double conv = 1.0319696543787917; // The log foot-candle to log lux conversion factor.
|
||||||
@ -99,7 +101,7 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
|||||||
yv = a * (sqrt(1.0 - e*e) * sin(eccAnom));
|
yv = a * (sqrt(1.0 - e*e) * sin(eccAnom));
|
||||||
v = atan2(yv, xv); // the moon's true anomaly
|
v = atan2(yv, xv); // the moon's true anomaly
|
||||||
r = sqrt (xv*xv + yv*yv); // and its distance
|
r = sqrt (xv*xv + yv*yv); // and its distance
|
||||||
|
|
||||||
// repetitive calculations, minimised for speed
|
// repetitive calculations, minimised for speed
|
||||||
cosN = cos(N);
|
cosN = cos(N);
|
||||||
sinN = sin(N);
|
sinN = sin(N);
|
||||||
@ -118,7 +120,7 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
|||||||
lonEcl = atan2 (yh, xh);
|
lonEcl = atan2 (yh, xh);
|
||||||
latEcl = atan2(zh, sqrt(xh*xh + yh*yh));
|
latEcl = atan2(zh, sqrt(xh*xh + yh*yh));
|
||||||
|
|
||||||
/* Calculate a number of perturbation, i.e. disturbances caused by the
|
/* Calculate a number of perturbation, i.e. disturbances caused by the
|
||||||
* gravitational influence of the sun and the other major planets.
|
* gravitational influence of the sun and the other major planets.
|
||||||
* The largest of these even have a name */
|
* The largest of these even have a name */
|
||||||
Ls = ourSun->getM() + ourSun->getw();
|
Ls = ourSun->getM() + ourSun->getw();
|
||||||
@ -130,7 +132,7 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
|||||||
twoM = 2 * M;
|
twoM = 2 * M;
|
||||||
FlesstwoD = F - twoD;
|
FlesstwoD = F - twoD;
|
||||||
MlesstwoD = M - twoD;
|
MlesstwoD = M - twoD;
|
||||||
|
|
||||||
lonEcl += SGD_DEGREES_TO_RADIANS * (-1.274 * sin(MlesstwoD)
|
lonEcl += SGD_DEGREES_TO_RADIANS * (-1.274 * sin(MlesstwoD)
|
||||||
+0.658 * sin(twoD)
|
+0.658 * sin(twoD)
|
||||||
-0.186 * sin(ourSun->getM())
|
-0.186 * sin(ourSun->getM())
|
||||||
@ -154,12 +156,13 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
|||||||
-0.46 * cos(twoD)
|
-0.46 * cos(twoD)
|
||||||
);
|
);
|
||||||
distance = r;
|
distance = r;
|
||||||
|
distance_in_a = r/a;
|
||||||
// SG_LOG(SG_GENERAL, SG_INFO, "Running moon update");
|
// SG_LOG(SG_GENERAL, SG_INFO, "Running moon update");
|
||||||
rcoslatEcl = r * cos(latEcl);
|
rcoslatEcl = r * cos(latEcl);
|
||||||
xg = cos(lonEcl) * rcoslatEcl;
|
xg = cos(lonEcl) * rcoslatEcl;
|
||||||
yg = sin(lonEcl) * rcoslatEcl;
|
yg = sin(lonEcl) * rcoslatEcl;
|
||||||
zg = r * sin(latEcl);
|
zg = r * sin(latEcl);
|
||||||
|
|
||||||
xe = xg;
|
xe = xg;
|
||||||
ye = yg * cosecl -zg * sinecl;
|
ye = yg * cosecl -zg * sinecl;
|
||||||
ze = yg * sinecl +zg * cosecl;
|
ze = yg * sinecl +zg * cosecl;
|
||||||
@ -167,17 +170,17 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
|||||||
geoRa = atan2(ye, xe);
|
geoRa = atan2(ye, xe);
|
||||||
geoDec = atan2(ze, sqrt(xe*xe + ye*ye));
|
geoDec = atan2(ze, sqrt(xe*xe + ye*ye));
|
||||||
|
|
||||||
/* SG_LOG( SG_GENERAL, SG_INFO,
|
/* SG_LOG( SG_GENERAL, SG_INFO,
|
||||||
"(geocentric) geoRa = (" << (SGD_RADIANS_TO_DEGREES * geoRa)
|
"(geocentric) geoRa = (" << (SGD_RADIANS_TO_DEGREES * geoRa)
|
||||||
<< "), geoDec= (" << (SGD_RADIANS_TO_DEGREES * geoDec) << ")" ); */
|
<< "), geoDec= (" << (SGD_RADIANS_TO_DEGREES * geoDec) << ")" ); */
|
||||||
|
|
||||||
|
|
||||||
// Given the moon's geocentric ra and dec, calculate its
|
// Given the moon's geocentric ra and dec, calculate its
|
||||||
// topocentric ra and dec. i.e. the position as seen from the
|
// topocentric ra and dec. i.e. the position as seen from the
|
||||||
// surface of the earth, instead of the center of the earth
|
// surface of the earth, instead of the center of the earth
|
||||||
|
|
||||||
// First calculate the moon's parallax, that is, the apparent size of the
|
// First calculate the moon's parallax, that is, the apparent size of the
|
||||||
// (equatorial) radius of the earth, as seen from the moon
|
// (equatorial) radius of the earth, as seen from the moon
|
||||||
mpar = asin ( 1 / r);
|
mpar = asin ( 1 / r);
|
||||||
// SG_LOG( SG_GENERAL, SG_INFO, "r = " << r << " mpar = " << mpar );
|
// SG_LOG( SG_GENERAL, SG_INFO, "r = " << r << " mpar = " << mpar );
|
||||||
// SG_LOG( SG_GENERAL, SG_INFO, "lat = " << f->get_Latitude() );
|
// SG_LOG( SG_GENERAL, SG_INFO, "lat = " << f->get_Latitude() );
|
||||||
@ -188,12 +191,12 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
|||||||
|
|
||||||
rho = 0.99883 + 0.00167 * cos(twolat);
|
rho = 0.99883 + 0.00167 * cos(twolat);
|
||||||
// SG_LOG( SG_GENERAL, SG_INFO, "rho = " << rho );
|
// SG_LOG( SG_GENERAL, SG_INFO, "rho = " << rho );
|
||||||
|
|
||||||
if (geoRa < 0)
|
if (geoRa < 0)
|
||||||
geoRa += SGD_2PI;
|
geoRa += SGD_2PI;
|
||||||
|
|
||||||
HA = lst - (3.8197186 * geoRa);
|
HA = lst - (3.8197186 * geoRa);
|
||||||
/* SG_LOG( SG_GENERAL, SG_INFO, "t->getLst() = " << t->getLst()
|
/* SG_LOG( SG_GENERAL, SG_INFO, "t->getLst() = " << t->getLst()
|
||||||
<< " HA = " << HA ); */
|
<< " HA = " << HA ); */
|
||||||
|
|
||||||
g = atan (tan(gclat) / cos ((HA / 3.8197186)));
|
g = atan (tan(gclat) / cos ((HA / 3.8197186)));
|
||||||
@ -212,8 +215,140 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
|||||||
// << SGD_RADIANS_TO_DEGREES * (geoDec - declination) << endl;
|
// << SGD_RADIANS_TO_DEGREES * (geoDec - declination) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SG_LOG( SG_GENERAL, SG_INFO,
|
/* SG_LOG( SG_GENERAL, SG_INFO,
|
||||||
"Ra = (" << (SGD_RADIANS_TO_DEGREES *rightAscension)
|
"Ra = (" << (SGD_RADIANS_TO_DEGREES *rightAscension)
|
||||||
|
<< "), Dec= (" << (SGD_RADIANS_TO_DEGREES *declination) << ")" ); */
|
||||||
|
|
||||||
|
// Moon age and phase calculation
|
||||||
|
age = lonEcl - ourSun->getlonEcl();
|
||||||
|
phase = (1 - cos(age)) / 2;
|
||||||
|
|
||||||
|
// The log of the illuminance of the moon outside the atmosphere.
|
||||||
|
// This is the base 10 log of equation 20 from Krisciunas K. and Schaefer B.E.
|
||||||
|
// (1991). A model of the brightness of moonlight, Publ. Astron. Soc. Pacif.
|
||||||
|
// 103(667), 1033-1039 (DOI: http://dx.doi.org/10.1086/132921).
|
||||||
|
alpha = SGD_RADIANS_TO_DEGREES * SGMiscd::normalizeAngle(age + SGMiscd::pi());
|
||||||
|
log_I = -0.4 * (3.84 + 0.026*fabs(alpha) + 4e-9*pow(alpha, 4.0));
|
||||||
|
|
||||||
|
// Convert from foot-candles to lux.
|
||||||
|
log_I += conv;
|
||||||
|
|
||||||
|
// The moon's illuminance factor, bracketed between 0 and 1.
|
||||||
|
I_factor = (log_I - max_loglux) / (max_loglux - min_loglux) + 1.0;
|
||||||
|
I_factor = SGMiscd::clip(I_factor, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* void MoonPos::updatePosition(double mjd, Star *ourSun) this member
|
||||||
|
* function calculates the geocentric position (i.e.) the position of
|
||||||
|
* the moon as seen from the center of earth. As such, it does not
|
||||||
|
* include any parallax effects. These are taken into account during
|
||||||
|
* the rendering.
|
||||||
|
****************************************************************************/
|
||||||
|
void MoonPos::updatePosition(double mjd, Star *ourSun)
|
||||||
|
{
|
||||||
|
double
|
||||||
|
eccAnom, ecl, actTime,
|
||||||
|
xv, yv, v, r, xh, yh, zh, zg, xe,
|
||||||
|
Ls, Lm, D, F, geoRa, geoDec,
|
||||||
|
cosN, sinN, cosvw, sinvw, sinvw_cosi, cosecl, sinecl, rcoslatEcl,
|
||||||
|
FlesstwoD, MlesstwoD, twoD, twoM, twolat, alpha;
|
||||||
|
|
||||||
|
double max_loglux = -0.504030345621;
|
||||||
|
double min_loglux = -4.39964634562;
|
||||||
|
double conv = 1.0319696543787917; // The log foot-candle to log lux conversion factor.
|
||||||
|
updateOrbElements(mjd);
|
||||||
|
actTime = sgCalcActTime(mjd);
|
||||||
|
|
||||||
|
// calculate the angle between ecliptic and equatorial coordinate system
|
||||||
|
// in Radians
|
||||||
|
ecl = SGD_DEGREES_TO_RADIANS * (23.4393 - 3.563E-7 * actTime);
|
||||||
|
eccAnom = sgCalcEccAnom(M, e); // Calculate the eccentric anomaly
|
||||||
|
xv = a * (cos(eccAnom) - e);
|
||||||
|
yv = a * (sqrt(1.0 - e*e) * sin(eccAnom));
|
||||||
|
v = atan2(yv, xv); // the moon's true anomaly
|
||||||
|
r = sqrt (xv*xv + yv*yv); // and its distance
|
||||||
|
|
||||||
|
// repetitive calculations, minimised for speed
|
||||||
|
cosN = cos(N);
|
||||||
|
sinN = sin(N);
|
||||||
|
cosvw = cos(v+w);
|
||||||
|
sinvw = sin(v+w);
|
||||||
|
sinvw_cosi = sinvw * cos(i);
|
||||||
|
cosecl = cos(ecl);
|
||||||
|
sinecl = sin(ecl);
|
||||||
|
|
||||||
|
// estimate the geocentric rectangular coordinates here
|
||||||
|
xh = r * (cosN * cosvw - sinN * sinvw_cosi);
|
||||||
|
yh = r * (sinN * cosvw + cosN * sinvw_cosi);
|
||||||
|
zh = r * (sinvw * sin(i));
|
||||||
|
|
||||||
|
// calculate the ecliptic latitude and longitude here
|
||||||
|
lonEcl = atan2 (yh, xh);
|
||||||
|
latEcl = atan2(zh, sqrt(xh*xh + yh*yh));
|
||||||
|
|
||||||
|
/* Calculate a number of perturbation, i.e. disturbances caused by the
|
||||||
|
* gravitational influence of the sun and the other major planets.
|
||||||
|
* The largest of these even have a name */
|
||||||
|
Ls = ourSun->getM() + ourSun->getw();
|
||||||
|
Lm = M + w + N;
|
||||||
|
D = Lm - Ls;
|
||||||
|
F = Lm - N;
|
||||||
|
|
||||||
|
twoD = 2 * D;
|
||||||
|
twoM = 2 * M;
|
||||||
|
FlesstwoD = F - twoD;
|
||||||
|
MlesstwoD = M - twoD;
|
||||||
|
|
||||||
|
lonEcl += SGD_DEGREES_TO_RADIANS * (-1.274 * sin(MlesstwoD)
|
||||||
|
+0.658 * sin(twoD)
|
||||||
|
-0.186 * sin(ourSun->getM())
|
||||||
|
-0.059 * sin(twoM - twoD)
|
||||||
|
-0.057 * sin(MlesstwoD + ourSun->getM())
|
||||||
|
+0.053 * sin(M + twoD)
|
||||||
|
+0.046 * sin(twoD - ourSun->getM())
|
||||||
|
+0.041 * sin(M - ourSun->getM())
|
||||||
|
-0.035 * sin(D)
|
||||||
|
-0.031 * sin(M + ourSun->getM())
|
||||||
|
-0.015 * sin(2*F - twoD)
|
||||||
|
+0.011 * sin(M - 4*D)
|
||||||
|
);
|
||||||
|
latEcl += SGD_DEGREES_TO_RADIANS * (-0.173 * sin(FlesstwoD)
|
||||||
|
-0.055 * sin(M - FlesstwoD)
|
||||||
|
-0.046 * sin(M + FlesstwoD)
|
||||||
|
+0.033 * sin(F + twoD)
|
||||||
|
+0.017 * sin(twoM + F)
|
||||||
|
);
|
||||||
|
r += (-0.58 * cos(MlesstwoD)
|
||||||
|
-0.46 * cos(twoD)
|
||||||
|
);
|
||||||
|
// from the orbital elements, the unit of the distance is in Earth radius, around 60.
|
||||||
|
distance = r;
|
||||||
|
distance_in_a = r/a;
|
||||||
|
// SG_LOG(SG_GENERAL, SG_INFO, "Running moon update");
|
||||||
|
rcoslatEcl = r * cos(latEcl);
|
||||||
|
xg = cos(lonEcl) * rcoslatEcl;
|
||||||
|
yg = sin(lonEcl) * rcoslatEcl;
|
||||||
|
zg = r * sin(latEcl);
|
||||||
|
|
||||||
|
xe = xg;
|
||||||
|
ye = yg * cosecl -zg * sinecl;
|
||||||
|
ze = yg * sinecl +zg * cosecl;
|
||||||
|
|
||||||
|
geoRa = atan2(ye, xe);
|
||||||
|
geoDec = atan2(ze, sqrt(xe*xe + ye*ye));
|
||||||
|
|
||||||
|
if (geoRa < 0)
|
||||||
|
geoRa += SGD_2PI;
|
||||||
|
|
||||||
|
rightAscension = geoRa;
|
||||||
|
declination = geoDec;
|
||||||
|
|
||||||
|
|
||||||
|
/* SG_LOG( SG_GENERAL, SG_INFO,
|
||||||
|
"Ra = (" << (SGD_RADIANS_TO_DEGREES *rightAscension)
|
||||||
<< "), Dec= (" << (SGD_RADIANS_TO_DEGREES *declination) << ")" ); */
|
<< "), Dec= (" << (SGD_RADIANS_TO_DEGREES *declination) << ")" ); */
|
||||||
|
|
||||||
// Moon age and phase calculation
|
// Moon age and phase calculation
|
||||||
|
@ -39,6 +39,7 @@ private:
|
|||||||
double xg, yg; // the moon's rectangular geocentric coordinates
|
double xg, yg; // the moon's rectangular geocentric coordinates
|
||||||
double ye, ze; // the moon's rectangular equatorial coordinates
|
double ye, ze; // the moon's rectangular equatorial coordinates
|
||||||
double distance; // the moon's distance to the earth
|
double distance; // the moon's distance to the earth
|
||||||
|
double distance_in_a; // the moon's distance to the earth in unit of its semi-mayor axis a
|
||||||
double age; // the moon's age from 0 to 2pi
|
double age; // the moon's age from 0 to 2pi
|
||||||
double phase; // the moon's phase
|
double phase; // the moon's phase
|
||||||
double log_I; // the moon's illuminance outside the atmosphere (logged)
|
double log_I; // the moon's illuminance outside the atmosphere (logged)
|
||||||
@ -59,8 +60,9 @@ public:
|
|||||||
MoonPos(double mjd);
|
MoonPos(double mjd);
|
||||||
MoonPos();
|
MoonPos();
|
||||||
~MoonPos();
|
~MoonPos();
|
||||||
void updatePosition(double mjd, double lst, double lat, Star *ourSun);
|
void updatePositionTopo(double mjd, double lst, double lat, Star *ourSun);
|
||||||
// void newImage();
|
void updatePosition(double mjd, Star *ourSun);
|
||||||
|
// void newImage();
|
||||||
double getM() const;
|
double getM() const;
|
||||||
double getw() const;
|
double getw() const;
|
||||||
double getxg() const;
|
double getxg() const;
|
||||||
@ -68,6 +70,7 @@ public:
|
|||||||
double getye() const;
|
double getye() const;
|
||||||
double getze() const;
|
double getze() const;
|
||||||
double getDistance() const;
|
double getDistance() const;
|
||||||
|
double getDistanceInMayorAxis() const;
|
||||||
double getAge() const;
|
double getAge() const;
|
||||||
double getPhase() const;
|
double getPhase() const;
|
||||||
double getLogIlluminance() const;
|
double getLogIlluminance() const;
|
||||||
@ -109,6 +112,11 @@ inline double MoonPos::getDistance() const
|
|||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline double MoonPos::getDistanceInMayorAxis() const
|
||||||
|
{
|
||||||
|
return distance_in_a;
|
||||||
|
}
|
||||||
|
|
||||||
inline double MoonPos::getAge() const
|
inline double MoonPos::getAge() const
|
||||||
{
|
{
|
||||||
return age;
|
return age;
|
||||||
|
@ -82,7 +82,7 @@ inline T magnitude2(const simd4_t<T,N>& vi) {
|
|||||||
|
|
||||||
template<typename T, int N>
|
template<typename T, int N>
|
||||||
inline simd4_t<T,N> interpolate(T tau, const simd4_t<T,N>& v1, const simd4_t<T,N>& v2) {
|
inline simd4_t<T,N> interpolate(T tau, const simd4_t<T,N>& v1, const simd4_t<T,N>& v2) {
|
||||||
return (T(1)-tau)*v1 + tau*v2;
|
return v1 + tau*(v2-v1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, int N>
|
template<typename T, int N>
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
// moon.hxx -- model earth's moon
|
// moon.hxx -- model earth's moon
|
||||||
//
|
//
|
||||||
// Written by Durk Talsma. Originally started October 1997, for distribution
|
// Written by Durk Talsma. Originally started October 1997, for distribution
|
||||||
// with the FlightGear project. Version 2 was written in August and
|
// with the FlightGear project. Version 2 was written in August and
|
||||||
// September 1998. This code is based upon algorithms and data kindly
|
// September 1998. This code is based upon algorithms and data kindly
|
||||||
// provided by Mr. Paul Schlyter. (pausch@saaf.se).
|
// provided by Mr. Paul Schlyter. (pausch@saaf.se).
|
||||||
//
|
//
|
||||||
// Separated out rendering pieces and converted to ssg by Curt Olson,
|
// Separated out rendering pieces and converted to ssg by Curt Olson,
|
||||||
// March 2000
|
// March 2000
|
||||||
@ -69,7 +69,7 @@ SGMoon::~SGMoon( void ) {
|
|||||||
osg::Node*
|
osg::Node*
|
||||||
SGMoon::build( SGPath path, double moon_size ) {
|
SGMoon::build( SGPath path, double moon_size ) {
|
||||||
|
|
||||||
osg::Node* orb = SGMakeSphere(moon_size, 15, 15);
|
osg::Node* orb = SGMakeSphere(moon_size, 40, 20);
|
||||||
osg::StateSet* stateSet = orb->getOrCreateStateSet();
|
osg::StateSet* stateSet = orb->getOrCreateStateSet();
|
||||||
stateSet->setRenderBinDetails(-5, "RenderBin");
|
stateSet->setRenderBinDetails(-5, "RenderBin");
|
||||||
|
|
||||||
@ -141,18 +141,18 @@ bool SGMoon::repaint( double moon_angle ) {
|
|||||||
prev_moon_angle = moon_angle;
|
prev_moon_angle = moon_angle;
|
||||||
|
|
||||||
float moon_factor = 4*cos(moon_angle);
|
float moon_factor = 4*cos(moon_angle);
|
||||||
|
|
||||||
if (moon_factor > 1) moon_factor = 1.0;
|
if (moon_factor > 1) moon_factor = 1.0;
|
||||||
if (moon_factor < -1) moon_factor = -1.0;
|
if (moon_factor < -1) moon_factor = -1.0;
|
||||||
moon_factor = moon_factor/2 + 0.5;
|
moon_factor = moon_factor/2 + 0.5;
|
||||||
|
|
||||||
osg::Vec4 color;
|
osg::Vec4 color;
|
||||||
color[1] = sqrt(moon_factor);
|
color[1] = sqrt(moon_factor);
|
||||||
color[0] = sqrt(color[1]);
|
color[0] = sqrt(color[1]);
|
||||||
color[2] = moon_factor * moon_factor;
|
color[2] = moon_factor * moon_factor;
|
||||||
color[2] *= color[2];
|
color[2] *= color[2];
|
||||||
color[3] = 1.0;
|
color[3] = 1.0;
|
||||||
|
|
||||||
gamma_correct_rgb( color._v );
|
gamma_correct_rgb( color._v );
|
||||||
|
|
||||||
orb_material->setDiffuse(osg::Material::FRONT_AND_BACK, color);
|
orb_material->setDiffuse(osg::Material::FRONT_AND_BACK, color);
|
||||||
@ -162,22 +162,74 @@ bool SGMoon::repaint( double moon_angle ) {
|
|||||||
|
|
||||||
|
|
||||||
// reposition the moon at the specified right ascension and
|
// reposition the moon at the specified right ascension and
|
||||||
// declination, offset by our current position (p) so that it appears
|
// declination from the center of Earth. Because the view is actually
|
||||||
// fixed at a great distance from the viewer. Also add in an optional
|
// offset by our current position (p), we first evaluate our current
|
||||||
// rotation (i.e. for the current time of day.)
|
// position w.r.t the Moon and then shift to the articial center of
|
||||||
bool SGMoon::reposition( double rightAscension, double declination,
|
// earth before shifting to the rendered moon distance. This allows to
|
||||||
double moon_dist )
|
// implement any parallax effects. moon_dist_bare is expected to not
|
||||||
{
|
// change during the rendering, it gives us the normalisation factors
|
||||||
osg::Matrix T2, RA, DEC;
|
// between real distances and units used in the
|
||||||
|
// rendering. moon_dist_fact is any extra factors to put the moon
|
||||||
|
// further or closer.
|
||||||
|
|
||||||
|
|
||||||
|
bool SGMoon::reposition( double rightAscension, double declination,
|
||||||
|
double moon_dist_bare, double moon_dist_factor,
|
||||||
|
double lst, double lat, double alt )
|
||||||
|
{
|
||||||
|
osg::Matrix TE, T2, RA, DEC;
|
||||||
|
|
||||||
|
// semi mayor axis
|
||||||
|
const double moon_a_in_rearth = 60.266600;
|
||||||
|
// average (we could also account for equatorial streching like in
|
||||||
|
// oursun.cxx if required)
|
||||||
|
const double earth_radius_in_meters = 6371000.0;
|
||||||
|
//local hour angle in radians
|
||||||
|
double lha;
|
||||||
|
// in unit of the rendering
|
||||||
|
double moon_dist;
|
||||||
|
double earth_radius, viewer_radius;
|
||||||
|
double xp,yp,zp;
|
||||||
|
|
||||||
|
//rendered earth radius according to what has been specified by
|
||||||
|
//moon_dist_bare
|
||||||
|
earth_radius = moon_dist_bare/moon_a_in_rearth;
|
||||||
|
|
||||||
|
//how far are we from the center of Earth
|
||||||
|
viewer_radius = (1.0 + alt/earth_radius_in_meters)*earth_radius;
|
||||||
|
|
||||||
|
// the local hour angle of the moon, .i.e. its angle with respect
|
||||||
|
// to the meridian of the viewer
|
||||||
|
lha = lst - rightAscension;
|
||||||
|
|
||||||
|
// the shift vector of the observer w.r.t. earth center (funny
|
||||||
|
// convention on x?)
|
||||||
|
zp = viewer_radius * sin(lat);
|
||||||
|
yp = viewer_radius * cos(lat)*cos(lha);
|
||||||
|
xp = viewer_radius * cos(lat)*sin(-lha);
|
||||||
|
|
||||||
|
//rotate along the z axis
|
||||||
RA.makeRotate(rightAscension - 90.0 * SGD_DEGREES_TO_RADIANS,
|
RA.makeRotate(rightAscension - 90.0 * SGD_DEGREES_TO_RADIANS,
|
||||||
osg::Vec3(0, 0, 1));
|
osg::Vec3(0, 0, 1));
|
||||||
|
//rotate along the rotated x axis
|
||||||
DEC.makeRotate(declination, osg::Vec3(1, 0, 0));
|
DEC.makeRotate(declination, osg::Vec3(1, 0, 0));
|
||||||
|
|
||||||
|
//move to the center of Earth
|
||||||
|
TE.makeTranslate(osg::Vec3(-xp,-yp,-zp));
|
||||||
|
|
||||||
|
//move the moon from the center of Earth to moon_dist
|
||||||
|
moon_dist = moon_dist_bare * moon_dist_factor;
|
||||||
T2.makeTranslate(osg::Vec3(0, moon_dist, 0));
|
T2.makeTranslate(osg::Vec3(0, moon_dist, 0));
|
||||||
|
|
||||||
moon_transform->setMatrix(T2*DEC*RA);
|
// cout << " viewer radius= " << viewer_radius << endl;
|
||||||
|
// cout << " xp yp zp= " << xp <<" " << yp << " " << zp << endl;
|
||||||
|
// cout << " lha= " << lha << endl;
|
||||||
|
// cout << " moon_dist_bare= " << moon_dist_bare << endl;
|
||||||
|
// cout << " moon_dist_factor= " << moon_dist_factor << endl;
|
||||||
|
// cout << " moon_dist= " << moon_dist << endl;
|
||||||
|
|
||||||
|
moon_transform->setMatrix(T2*TE*DEC*RA);
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -65,11 +65,12 @@ public:
|
|||||||
bool repaint( double moon_angle );
|
bool repaint( double moon_angle );
|
||||||
|
|
||||||
// reposition the moon at the specified right ascension and
|
// reposition the moon at the specified right ascension and
|
||||||
// declination, offset by our current position (p) so that it
|
// declination, at moon_dist_bare*moon_dist_factor from the center
|
||||||
// appears fixed at a great distance from the viewer. Also add in
|
// of Earth. lst, lat and alt are need to estimate where is the
|
||||||
// an optional rotation (i.e. for the current time of day.)
|
// center of Earth from the current view).
|
||||||
bool reposition( double rightAscension, double declination,
|
bool reposition( double rightAscension, double declination,
|
||||||
double moon_dist );
|
double moon_dist_bare, double moon_dist_factor,
|
||||||
|
double lst, double lat, double alt );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ bool SGSky::reposition( const SGSkyState &st, const SGEphemeris& eph, double dt
|
|||||||
double angleRad = SGMiscd::deg2rad(angle);
|
double angleRad = SGMiscd::deg2rad(angle);
|
||||||
|
|
||||||
SGVec3f zero_elev, view_up;
|
SGVec3f zero_elev, view_up;
|
||||||
double lon, lat, alt;
|
double lon, lat, alt, lst;
|
||||||
|
|
||||||
SGGeod geodZeroViewPos = SGGeod::fromGeodM(st.pos_geod, 0);
|
SGGeod geodZeroViewPos = SGGeod::fromGeodM(st.pos_geod, 0);
|
||||||
zero_elev = toVec3f( SGVec3d::fromGeod(geodZeroViewPos) );
|
zero_elev = toVec3f( SGVec3d::fromGeod(geodZeroViewPos) );
|
||||||
@ -165,7 +165,9 @@ bool SGSky::reposition( const SGSkyState &st, const SGEphemeris& eph, double dt
|
|||||||
lon = st.pos_geod.getLongitudeRad();
|
lon = st.pos_geod.getLongitudeRad();
|
||||||
lat = st.pos_geod.getLatitudeRad();
|
lat = st.pos_geod.getLatitudeRad();
|
||||||
alt = st.pos_geod.getElevationM();
|
alt = st.pos_geod.getElevationM();
|
||||||
|
// Local sidereal time
|
||||||
|
lst = angleRad + lon;
|
||||||
|
|
||||||
dome->reposition( zero_elev, alt, lon, lat, st.spin );
|
dome->reposition( zero_elev, alt, lon, lat, st.spin );
|
||||||
|
|
||||||
osg::Matrix m = osg::Matrix::rotate(angleRad, osg::Vec3(0, 0, -1));
|
osg::Matrix m = osg::Matrix::rotate(angleRad, osg::Vec3(0, 0, -1));
|
||||||
@ -178,7 +180,12 @@ bool SGSky::reposition( const SGSkyState &st, const SGEphemeris& eph, double dt
|
|||||||
|
|
||||||
double moon_ra = eph.getMoonRightAscension();
|
double moon_ra = eph.getMoonRightAscension();
|
||||||
double moon_dec = eph.getMoonDeclination();
|
double moon_dec = eph.getMoonDeclination();
|
||||||
moon->reposition( moon_ra, moon_dec, st.moon_dist );
|
double moon_r = eph.getMoonDistanceInMayorAxis();
|
||||||
|
|
||||||
|
//this allows to render the moon closer to the viewer when the
|
||||||
|
//moon is closer to the center of Earth, times any articial extra factors
|
||||||
|
double moon_dist_factor = moon_r * st.moon_dist_factor;
|
||||||
|
moon->reposition( moon_ra, moon_dec, st.moon_dist_bare, moon_dist_factor, lst, lat, alt );
|
||||||
|
|
||||||
for ( unsigned i = 0; i < cloud_layers.size(); ++i ) {
|
for ( unsigned i = 0; i < cloud_layers.size(); ++i ) {
|
||||||
if ( cloud_layers[i]->getCoverage() != SGCloudLayer::SG_CLOUD_CLEAR ||
|
if ( cloud_layers[i]->getCoverage() != SGCloudLayer::SG_CLOUD_CLEAR ||
|
||||||
|
@ -63,7 +63,8 @@ struct SGSkyState
|
|||||||
double gst; //!< GMT side real time.
|
double gst; //!< GMT side real time.
|
||||||
double sun_dist; //!< the sun's distance from the current view point
|
double sun_dist; //!< the sun's distance from the current view point
|
||||||
// (to keep it inside your view volume).
|
// (to keep it inside your view volume).
|
||||||
double moon_dist;//!< The moon's distance from the current view point.
|
double moon_dist_bare ;//!< The moon's semi-mayor axis in the rendering (constant)
|
||||||
|
double moon_dist_factor ;//!< Any factor that are needed to artificially change the moon distance
|
||||||
double sun_angle;
|
double sun_angle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user