# In the Vr template ,there is not day-night cycle. But how to control the moon position by time like the real world? Is there any function?

## Recommended Posts

Hello!

Here i control the sun position by this function:

void AppWorldLogic::sunPosition(double & elevation, double& azimuth, double lat, double lon, int year , int month , int day , double hour , int min , int sec) {
double pi = 3.141592650f;
double twopi = 2 * pi;
double deg2rad = pi / 180.0f;

// get a day of the year, e.g. Feb 1 = 32, Mar 1 = 61 on leap years
int month_days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 };
for (int i = 0; i<month; i++)
day += month_days[i];
int leapdays = (year % 4) == 0 && ((year % 400) == 0 || (year % 100) != 0) && day >= 60 && !(month == 2 && day == 60);
if (leapdays > 0) day++;

// Get Julian date - 2400000
hour += min / 60.0f + sec / 3600.0f; // hour plus fraction
double delta = year - 1949.0f;
double leap = int(delta / 4.0f); // former leapyears
double jd = 32916.5f + delta * 365 + leap + day + hour / 24.0f;

// calculating input for the Atronomer's almanach as the difference between
// the Julian date and JD 2451545.0 (noon, 1 January 2000)
double time = jd - 51545.0f;

// calculating mean longitude and mean anomaly
double mnlong = 280.460f + 0.9856474f * time;
mnlong = remainder(mnlong, 360);
if (mnlong < 0) mnlong += 360;
double mnanom = 357.528f + 0.9856003f * time;
mnanom = remainder(mnanom, 360);
if (mnanom < 0) mnanom += 360;

// calculating ecliptic longitude and obliquity of ecliptic
double eclong = mnlong + 1.915f * Math::sin(mnanom) + 0.020f * Math::sin(2 * mnanom);
eclong = remainder(eclong, 360);
if (eclong < 0) eclong += 360;
double oblqec = 23.439f - 0.0000004f * time;

// calculating celestial coordinates: right ascension and declination
double num = Math::cos(oblqec) * Math::sin(eclong);
double den = Math::cos(eclong);
double ra = Math::atan(num / den);
if (den < 0) ra += pi;
if (den >= 0 && num < 0) ra += twopi;
double dec = Math::asin(Math::sin(oblqec) * Math::sin(eclong));

// calculating local coordinates Greenwich mean sidereal time
double gmst = 6.697375f + 0.0657098242f * time + hour;
gmst = remainder(gmst, 24);
if (gmst < 0) gmst += 24.0f;

// calculating local mean sidereal time
double lmst = gmst + lon / 15.0f;
lmst = remainder(lmst, 24);
if (lmst < 0) lmst += 24.0f;
lmst = lmst * 15.0f * deg2rad;

// calculating hour angle
double ha = lmst - ra;
if (ha < -pi) ha += twopi;
if (ha > pi) ha -= twopi;

// calculating azimuth and elevation
elevation = Math::asin(Math::sin(dec) * Math::sin(lat) + Math::cos(dec) * Math::cos(lat) * Math::cos(ha));
azimuth = Math::asin(-Math::cos(dec) * Math::sin(ha) / Math::cos(elevation));

// for logic and names, see Spencer, J.W. 1989. Solar Energy. 42(4):353
int cosAzPos = (0 <= Math::sin(dec) - Math::sin(elevation) * Math::sin(lat));
int sinAzNeg = (Math::sin(azimuth) < 0);
if (cosAzPos && sinAzNeg) azimuth += twopi;
if (!cosAzPos) azimuth = pi - azimuth;

// return elevation and azimuth
}

There is no simple solution, you can try to combine various approaches that already has been published on the Internet and create your own method of moon position control.

Some of the useful Astronomy C/C++ sources you can find here: https://www.projectpluto.com/source.htm

Thanks!

How to submit a good bug report
---
FTP server for test scenes and user uploads: