2 using System.Collections;
3 using System.Collections.Generic;
14 [RequireComponent(typeof(Light))]
16 public class Sun : MonoBehaviour
19 public GameObject sliderAndText;
20 public Toggle sunLocationControl;
21 public Slider longitudeSlider;
22 public Slider latitudeSlider;
23 public Slider sunHourSlider;
24 public Slider sunMinuteSlider;
57 public void SetTime(
int hour,
int minutes) {
59 this.minutes = minutes;
68 this.longitude = longitude;
69 this.latitude = latitude;
79 public void SetUpdateSteps(
int i) {
83 public void SetTimeSpeed(
float speed) {
92 light = GetComponent<Light>();
95 minutes = time.Minute;
99 private void OnValidate()
101 time = date +
new TimeSpan(hour, minutes, 0);
104 private void FixedUpdate()
113 float sunLatitude=-66f;
114 float sunLongitude=-45f;
117 bool isActive = sunLocationControl.isOn;
118 sliderAndText.SetActive(isActive);
122 sunLatitude = longitudeSlider.value;
123 sunLongitude = latitudeSlider.value;
124 sunHour = (int)sunHourSlider.value;
125 sunMinute = (
int)sunMinuteSlider.value;
130 if(StaticTODSchema.IsActive )
132 sunLocationControl.isOn =
false;
133 Debug.Log(
"UI Control is set to " + sunLocationControl.isOn);
134 sunLatitude = StaticTODSchema.SunLatitude;
135 sunLongitude = StaticTODSchema.SunLongitude;
136 sunHour = StaticTODSchema.Hour;
137 sunMinute = StaticTODSchema.Minute;
141 StaticTODSchema.IsActive =
false;
147 time = time.AddSeconds(timeSpeed * Time.deltaTime);
151 frameStep = (frameStep + 1) % frameSteps;
161 Vector3 angles =
new Vector3();
164 SunPosition.CalculateSunPosition(time, (
double)latitude, (
double)longitude, out azi, out alt);
165 angles.x = (float)alt * Mathf.Rad2Deg;
166 angles.y = (
float)azi * Mathf.Rad2Deg;
168 transform.localRotation = Quaternion.Euler(angles);
169 light.intensity = Mathf.InverseLerp(-12, 0, angles.x);
180 public static class SunPosition
182 private const double Deg2Rad = Math.PI / 180.0;
183 private const double Rad2Deg = 180.0 / Math.PI;
200 public static void CalculateSunPosition(
201 DateTime dateTime,
double latitude,
double longitude, out
double outAzimuth, out
double outAltitude)
204 dateTime = dateTime.ToUniversalTime();
207 double julianDate = 367 * dateTime.Year -
208 (int)((7.0 / 4.0) * (dateTime.Year +
209 (int)((dateTime.Month + 9.0) / 12.0))) +
210 (int)((275.0 * dateTime.Month) / 9.0) +
211 dateTime.Day - 730531.5;
213 double julianCenturies = julianDate / 36525.0;
216 double siderealTimeHours = 6.6974 + 2400.0513 * julianCenturies;
218 double siderealTimeUT = siderealTimeHours +
219 (366.2422 / 365.2422) * (double)dateTime.TimeOfDay.TotalHours;
221 double siderealTime = siderealTimeUT * 15 + longitude;
224 julianDate += (
double)dateTime.TimeOfDay.TotalHours / 24.0;
225 julianCenturies = julianDate / 36525.0;
228 double meanLongitude = CorrectAngle(Deg2Rad *
229 (280.466 + 36000.77 * julianCenturies));
231 double meanAnomaly = CorrectAngle(Deg2Rad *
232 (357.529 + 35999.05 * julianCenturies));
234 double equationOfCenter = Deg2Rad * ((1.915 - 0.005 * julianCenturies) *
235 Math.Sin(meanAnomaly) + 0.02 * Math.Sin(2 * meanAnomaly));
237 double elipticalLongitude =
238 CorrectAngle(meanLongitude + equationOfCenter);
240 double obliquity = (23.439 - 0.013 * julianCenturies) * Deg2Rad;
243 double rightAscension = Math.Atan2(
244 Math.Cos(obliquity) * Math.Sin(elipticalLongitude),
245 Math.Cos(elipticalLongitude));
247 double declination = Math.Asin(
248 Math.Sin(rightAscension) * Math.Sin(obliquity));
251 double hourAngle = CorrectAngle(siderealTime * Deg2Rad) - rightAscension;
253 if (hourAngle > Math.PI)
255 hourAngle -= 2 * Math.PI;
258 double altitude = Math.Asin(Math.Sin(latitude * Deg2Rad) *
259 Math.Sin(declination) + Math.Cos(latitude * Deg2Rad) *
260 Math.Cos(declination) * Math.Cos(hourAngle));
264 double aziNom = -Math.Sin(hourAngle);
266 Math.Tan(declination) * Math.Cos(latitude * Deg2Rad) -
267 Math.Sin(latitude * Deg2Rad) * Math.Cos(hourAngle);
269 double azimuth = Math.Atan(aziNom / aziDenom);
277 azimuth += 2 * Math.PI;
280 outAltitude = altitude;
281 outAzimuth = azimuth;
289 private static double CorrectAngle(
double angleInRadians)
291 if (angleInRadians < 0)
293 return 2 * Math.PI - (Math.Abs(angleInRadians) % (2 * Math.PI));
295 else if (angleInRadians > 2 * Math.PI)
297 return angleInRadians % (2 * Math.PI);
301 return angleInRadians;