/
EarthBehavior.cs
117 lines (94 loc) · 3.63 KB
/
EarthBehavior.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
public class EarthBehavior : MonoBehaviour
{
private double speed, xPos, zPos, t, dT, E;
private float scaleFactor;
private Vector3 camPos, camDist, sunDist, iniScale, norm;
private Material mat;
private GameObject cam, date;
private const double tRev = 31556925.445; // number of seconds in a tropical year which is 365.24219265 days
private const double rotPerSec = .00417807; // number of degrees of rotation about Earth's axis per second; rotates 360 degrees in one sidereal day which is slightly less than a solar day
private DateTime dtPeri = new DateTime(2020, 1, 5, 7, 47, 0); // DateTime of Jan 2020 perihelion - Jan 5, 2020 07:47 UTC
// Start is called before the first frame update
void Start()
{
mat = GetComponent<Renderer>().material;
cam = GameObject.Find("Main Camera");
date = GameObject.Find("Date & Time");
iniScale = transform.localScale;
// Initialize t - the number of seconds since Jan 2020 perihelion
SetT(DateTime.UtcNow);
// Initialize Earth's rotation
transform.Rotate(Vector3.up, -116.75f - (float)(rotPerSec * t));
}
// Update is called once per frame
void Update()
{
// Get current speed multiplier from Date & Time
DateTimeDisplay dateObj = date.GetComponent("DateTimeDisplay") as DateTimeDisplay;
speed = dateObj.speed;
// Rotate Earth about axis
transform.Rotate(Vector3.up, (float)(-rotPerSec * speed * Time.deltaTime));
// Compute Earth's position as function of t
// E initially approximates the number of radians Earth has orbited since the perihelion
E = t/tRev*2*Math.PI;
// Iterate through Newton's Method 3 times to get progressively more precise values for E
E = NewtonsMethod(E, 3);
xPos = 1495.96329*Math.Cos(E) - 24.9825869;
zPos = 1495.75469*Math.Sqrt(1-(Math.Pow(1495.96329*Math.Cos(E), 2)/2237906.17));
if (t % tRev > tRev/2 && t>0 || t % tRev > -tRev/2 && t<0)
zPos = -zPos;
transform.position = new Vector3((float)xPos, 0, (float)zPos);
// Illuminate earth surface that's facing the sun
sunDist = -transform.position; //sunDist is earth-to-sun vector
mat.SetVector("_SunDir", sunDist.normalized);
// Adjust scale based on view mode
CamBehavior camObj = cam.GetComponent("CamBehavior") as CamBehavior;
if (camObj.GetView() == 3) {
scaleFactor = 1000;
transform.localScale = scaleFactor * iniScale;
}
else {
transform.localScale = iniScale;
}
t += speed*Time.deltaTime;
}
// Get the Earth's position
public Vector3 GetPosition() {
return transform.position;
}
// Get the object's transform
public Transform GetTransform() {
return transform;
}
// Get t
public double GetT() {
return t;
}
// Set t based on the given DateTime
public void SetT(DateTime dt) {
dT = t;
t = dt.Subtract(dtPeri).TotalSeconds;
dT = t - dT;
}
// Set the Earth's rotation - only to be called when changing the date through the Date Selection menu
public void SetRot(double t) {
transform.Rotate(Vector3.up, (float)(-rotPerSec * t));
}
// Get dT - the difference in seconds between the new time and previous time
public double GetDT() {
return dT;
}
// Recursive method for approximating the Earth's position as a function of t
public double NewtonsMethod(double E, int n) {
// Base case when n is 0
if (n < 1)
return E;
// Recursive case
else
return NewtonsMethod(E - (5022440.67*(E-.0167*Math.Sin(E))-t) / (5022440.67*(1-.0167*Math.Cos(E))), n-1);
}
}