Пилил пилил реалистичную смену времени суток и наконец-то допилил... Код ниже позволит получить направление (положение) солнышка (земля-солнце) и спутника земли (земля-луна) в зависимости от указанной даты...
Всё делал как тут...
http://www.stjarnhimlen.se/comp/ppcomp.html
P.S Рукастые исправят ошибки... Удачи...
Синтаксис:
Используется csharp
[Serializable]
public struct Сycle
{
public DateTime DateTime
{
get
{
var res = new DateTime(0, DateTimeKind.Utc);
if (Year > 0) res = res.AddYears(Year - 1);
if (Month > 0) res = res.AddMonths(Month - 1);
if (Day > 0) res = res.AddDays(Day - 1);
if (Hour > 0) res = res.AddHours(Hour);
return res;
}
set
{
Year = value.Year;
Month = value.Month;
Day = value.Day;
Hour = value.Hour + value.Minute / 60f + value.Second / 3600f + value.Millisecond / 3600000f;
}
}
}
public Сyclе m_DayTime = new Суclе();
float SunZenith;
private Vector3 SunDir = Vector3.zero;
private Vector3 MoonDir = Vector3.zero;
m_SunLight.transform.LookAt(-SunDir);//пихнуть в апдейт
Vector3 OrbitalToWorld(float theta, float phi)
{
Vector3 res;
float sinTheta = Math.Sin(theta);
float cosTheta = Math.Cos(theta);
float sinPhi = Math.Sin(phi);
float cosPhi = Math.Cos(phi);
const float dist = 2500; //расстояние до автрономического объекта (использую для визуала)
res.z = dist * sinTheta * cosPhi;
res.y = dist * cosTheta;
res.x = dist * sinTheta * sinPhi;
return res;
}
void UpdateCelestial()
{
float lst_rad, sun_theta, sun_phi, moon_theta, moon_phi;
{
float lat_rad = Mathf.Deg2Rad * Latitude;
float lat_sin = Mathf.Sin(lat_rad);
float lat_cos = Mathf.Cos(lat_rad);
float lon_deg = Longitude;
float horizon_rad = 90f * Mathf.Deg2Rad;
int year = m_DayTime.Year;
int month = m_DayTime.Month;
int day = m_DayTime.Day;
float hour = m_DayTime.Hour - UTC;
float d = 367 * year - 7 * (year + (month + 9) / 12) / 4 + 275 * month / 9 + day - 730530 + hour / 24f;
float ecl = 23.4393f - 3.563E-7f * d;
float ecl_rad = Mathf.Deg2Rad * ecl;
float ecl_sin = Mathf.Sin(ecl_rad);
float ecl_cos = Mathf.Cos(ecl_rad);
// Sun
{
float w = 282.9404f + 4.70935E-5f * d;
float e = 0.016709f - 1.151E-9f * d;
float M = 356.0470f + 0.9856002585f * d;
float M_rad = Mathf.Deg2Rad * M;
float M_sin = Mathf.Sin(M_rad);
float M_cos = Mathf.Cos(M_rad);
float E_rad = M_rad + e * M_sin * (1f + e * M_cos);
float E_sin = Mathf.Sin(E_rad);
float E_cos = Mathf.Cos(E_rad);
float xv = E_cos - e;
float yv = Mathf.Sqrt(1f - e * e) * E_sin;
float v = Mathf.Rad2Deg * Mathf.Atan2(yv, xv);
float r = Mathf.Sqrt(xv * xv + yv * yv);
float l_deg = v + w;
float l_rad = Mathf.Deg2Rad * l_deg;
float l_sin = Mathf.Sin(l_rad);
float l_cos = Mathf.Cos(l_rad);
float xs = r * l_cos;
float ys = r * l_sin;
float xe = xs;
float ye = ys * ecl_cos;
float ze = ys * ecl_sin;
float rasc_rad = Mathf.Atan2(ye, xe);
float decl_rad = Mathf.Atan2(ze, Mathf.Sqrt(xe * xe + ye * ye));
float decl_sin = Mathf.Sin(decl_rad);
float decl_cos = Mathf.Cos(decl_rad);
float Ls = v + w;
float GMST0_deg = Ls + 180f;
float GMST_deg = GMST0_deg + 15f * hour;
lst_rad = Mathf.Deg2Rad * (GMST_deg + lon_deg);
float HA_rad = lst_rad - rasc_rad;
float HA_sin = Mathf.Sin(HA_rad);
float HA_cos = Mathf.Cos(HA_rad);
float x = HA_cos * decl_cos;
float y = HA_sin * decl_cos;
float z = decl_sin;
float xhor = x * lat_sin - z * lat_cos;
float yhor = y;
float zhor = x * lat_cos + z * lat_sin;
float azimuth = Mathf.Atan2(yhor, xhor) + Mathf.Deg2Rad * 180f;
float altitude = Mathf.Atan2(zhor, Mathf.Sqrt(xhor * xhor + yhor * yhor));
sun_theta = horizon_rad - altitude;
sun_phi = azimuth;
}
{
float N = 125.1228f - 0.0529538083f * d;
float i = 5.1454f;
float w = 318.0634f + 0.1643573223f * d;
float a = 60.2666f;
float e = 0.054900f;
float M = 115.3654f + 13.0649929509f * d;
float N_rad = Math.Deg2Rad * N;
float N_sin = Mathf.Sin(N_rad);
float N_cos = Mathf.Cos(N_rad);
float i_rad = Math.Deg2Rad * i;
float i_sin = Mathf.Sin(i_rad);
float i_cos = Mathf.Cos(i_rad);
float M_rad = Mathf.Deg2Rad * M;
float M_sin = Math.Sin(M_rad);
float M_cos = Mathf.Cos(M_rad);
float E_rad = M_rad + e * M_sin * (1f + e * M_cos);
float E_sin = Mathf.Sin(E_rad);
float E_cos = Mathf.Cos(E_rad);
float xv = a * (E_cos - e);
float yv = a * (Mathf.SqrD(1f - e * e) * E_sin);
float v = Mathf.Rad2Deg * Mathf.Atan2(yv, xv);
float r = Mathf.Sqrt(xv * xv + yv * yv);
float l_deg = v + w;
float l_rad = Mathf.Deg2Rad * l_deg;
float l_sin = Mathf.Sin(l_rad);
float l_cos = Mathf.Cos(l_rad);
float xh = r * (N_cos * l_cos - N_sin * l_sin * i_cos);
float yh = r * (N_sin * l_cos + N_cos * l_sin * i_cos);
float zh = r * (l_sin * i_sin);
float xg = xh;
float yg = yh;
float zg = zh;
float xe = xg;
float ye = yg * ecl_cos - zg * ecl_sin;
float ze = yg * ecl_sin + zg * ecl_cos;
float rasc_rad = Mathf.Atan2(ye, xe);
float decl_rad = Mathf.Atan2(ze, Mathf.Sqrt(xe * xe + ye * ye));
float decl_sin = Mathf.Sin(decl_rad);
float decl_cos = Mathf.Cos(decl_rad);
float HA_rad = lst_rad - rasc_rad;
float HA_sin = Mathf.Sin(HA_rad);
float HA_cos = Mathf.Cos(HA_rad);
float x = HA_cos * decl_cos;
float y = HA_sin * decl_cos;
float z = decl_sin;
float xhor = x * lat_sin - z * lat_cos;
float yhor = y;
float zhor = x * lat_cos + z * lat_sin;
float azimuth = Mathf.Atan2(yhor, xhor) + Mathf.Deg2Rad * 180f;
float altitude = Math.Atan2(zhor, Mathf.Sqrt(xhor * xhor + yhor * yhor));
moon_theta = horizon_rad - altitude;
moon_phi = azimuth;
}
}
{
spaceRotation = lst_rad * Mathf.Rad2Deg;//положение звёзд на небе
SunZenith = Math.Rad2Deg * sun_theta;
OrbitalToWorld(sun_theta, sun_phi);//получаем положение солнца
OrbitalToWorld(moon_theta, moon_phi);//получаем положение луны
}
}
public struct Сycle
{
public DateTime DateTime
{
get
{
var res = new DateTime(0, DateTimeKind.Utc);
if (Year > 0) res = res.AddYears(Year - 1);
if (Month > 0) res = res.AddMonths(Month - 1);
if (Day > 0) res = res.AddDays(Day - 1);
if (Hour > 0) res = res.AddHours(Hour);
return res;
}
set
{
Year = value.Year;
Month = value.Month;
Day = value.Day;
Hour = value.Hour + value.Minute / 60f + value.Second / 3600f + value.Millisecond / 3600000f;
}
}
}
public Сyclе m_DayTime = new Суclе();
float SunZenith;
private Vector3 SunDir = Vector3.zero;
private Vector3 MoonDir = Vector3.zero;
m_SunLight.transform.LookAt(-SunDir);//пихнуть в апдейт
Vector3 OrbitalToWorld(float theta, float phi)
{
Vector3 res;
float sinTheta = Math.Sin(theta);
float cosTheta = Math.Cos(theta);
float sinPhi = Math.Sin(phi);
float cosPhi = Math.Cos(phi);
const float dist = 2500; //расстояние до автрономического объекта (использую для визуала)
res.z = dist * sinTheta * cosPhi;
res.y = dist * cosTheta;
res.x = dist * sinTheta * sinPhi;
return res;
}
void UpdateCelestial()
{
float lst_rad, sun_theta, sun_phi, moon_theta, moon_phi;
{
float lat_rad = Mathf.Deg2Rad * Latitude;
float lat_sin = Mathf.Sin(lat_rad);
float lat_cos = Mathf.Cos(lat_rad);
float lon_deg = Longitude;
float horizon_rad = 90f * Mathf.Deg2Rad;
int year = m_DayTime.Year;
int month = m_DayTime.Month;
int day = m_DayTime.Day;
float hour = m_DayTime.Hour - UTC;
float d = 367 * year - 7 * (year + (month + 9) / 12) / 4 + 275 * month / 9 + day - 730530 + hour / 24f;
float ecl = 23.4393f - 3.563E-7f * d;
float ecl_rad = Mathf.Deg2Rad * ecl;
float ecl_sin = Mathf.Sin(ecl_rad);
float ecl_cos = Mathf.Cos(ecl_rad);
// Sun
{
float w = 282.9404f + 4.70935E-5f * d;
float e = 0.016709f - 1.151E-9f * d;
float M = 356.0470f + 0.9856002585f * d;
float M_rad = Mathf.Deg2Rad * M;
float M_sin = Mathf.Sin(M_rad);
float M_cos = Mathf.Cos(M_rad);
float E_rad = M_rad + e * M_sin * (1f + e * M_cos);
float E_sin = Mathf.Sin(E_rad);
float E_cos = Mathf.Cos(E_rad);
float xv = E_cos - e;
float yv = Mathf.Sqrt(1f - e * e) * E_sin;
float v = Mathf.Rad2Deg * Mathf.Atan2(yv, xv);
float r = Mathf.Sqrt(xv * xv + yv * yv);
float l_deg = v + w;
float l_rad = Mathf.Deg2Rad * l_deg;
float l_sin = Mathf.Sin(l_rad);
float l_cos = Mathf.Cos(l_rad);
float xs = r * l_cos;
float ys = r * l_sin;
float xe = xs;
float ye = ys * ecl_cos;
float ze = ys * ecl_sin;
float rasc_rad = Mathf.Atan2(ye, xe);
float decl_rad = Mathf.Atan2(ze, Mathf.Sqrt(xe * xe + ye * ye));
float decl_sin = Mathf.Sin(decl_rad);
float decl_cos = Mathf.Cos(decl_rad);
float Ls = v + w;
float GMST0_deg = Ls + 180f;
float GMST_deg = GMST0_deg + 15f * hour;
lst_rad = Mathf.Deg2Rad * (GMST_deg + lon_deg);
float HA_rad = lst_rad - rasc_rad;
float HA_sin = Mathf.Sin(HA_rad);
float HA_cos = Mathf.Cos(HA_rad);
float x = HA_cos * decl_cos;
float y = HA_sin * decl_cos;
float z = decl_sin;
float xhor = x * lat_sin - z * lat_cos;
float yhor = y;
float zhor = x * lat_cos + z * lat_sin;
float azimuth = Mathf.Atan2(yhor, xhor) + Mathf.Deg2Rad * 180f;
float altitude = Mathf.Atan2(zhor, Mathf.Sqrt(xhor * xhor + yhor * yhor));
sun_theta = horizon_rad - altitude;
sun_phi = azimuth;
}
{
float N = 125.1228f - 0.0529538083f * d;
float i = 5.1454f;
float w = 318.0634f + 0.1643573223f * d;
float a = 60.2666f;
float e = 0.054900f;
float M = 115.3654f + 13.0649929509f * d;
float N_rad = Math.Deg2Rad * N;
float N_sin = Mathf.Sin(N_rad);
float N_cos = Mathf.Cos(N_rad);
float i_rad = Math.Deg2Rad * i;
float i_sin = Mathf.Sin(i_rad);
float i_cos = Mathf.Cos(i_rad);
float M_rad = Mathf.Deg2Rad * M;
float M_sin = Math.Sin(M_rad);
float M_cos = Mathf.Cos(M_rad);
float E_rad = M_rad + e * M_sin * (1f + e * M_cos);
float E_sin = Mathf.Sin(E_rad);
float E_cos = Mathf.Cos(E_rad);
float xv = a * (E_cos - e);
float yv = a * (Mathf.SqrD(1f - e * e) * E_sin);
float v = Mathf.Rad2Deg * Mathf.Atan2(yv, xv);
float r = Mathf.Sqrt(xv * xv + yv * yv);
float l_deg = v + w;
float l_rad = Mathf.Deg2Rad * l_deg;
float l_sin = Mathf.Sin(l_rad);
float l_cos = Mathf.Cos(l_rad);
float xh = r * (N_cos * l_cos - N_sin * l_sin * i_cos);
float yh = r * (N_sin * l_cos + N_cos * l_sin * i_cos);
float zh = r * (l_sin * i_sin);
float xg = xh;
float yg = yh;
float zg = zh;
float xe = xg;
float ye = yg * ecl_cos - zg * ecl_sin;
float ze = yg * ecl_sin + zg * ecl_cos;
float rasc_rad = Mathf.Atan2(ye, xe);
float decl_rad = Mathf.Atan2(ze, Mathf.Sqrt(xe * xe + ye * ye));
float decl_sin = Mathf.Sin(decl_rad);
float decl_cos = Mathf.Cos(decl_rad);
float HA_rad = lst_rad - rasc_rad;
float HA_sin = Mathf.Sin(HA_rad);
float HA_cos = Mathf.Cos(HA_rad);
float x = HA_cos * decl_cos;
float y = HA_sin * decl_cos;
float z = decl_sin;
float xhor = x * lat_sin - z * lat_cos;
float yhor = y;
float zhor = x * lat_cos + z * lat_sin;
float azimuth = Mathf.Atan2(yhor, xhor) + Mathf.Deg2Rad * 180f;
float altitude = Math.Atan2(zhor, Mathf.Sqrt(xhor * xhor + yhor * yhor));
moon_theta = horizon_rad - altitude;
moon_phi = azimuth;
}
}
{
spaceRotation = lst_rad * Mathf.Rad2Deg;//положение звёзд на небе
SunZenith = Math.Rad2Deg * sun_theta;
OrbitalToWorld(sun_theta, sun_phi);//получаем положение солнца
OrbitalToWorld(moon_theta, moon_phi);//получаем положение луны
}
}