Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
CalendricalCalculationsHelper.cs
Go to the documentation of this file.
2
3internal static class CalendricalCalculationsHelper
4{
14
16 {
17 internal int _lowestYear;
18
20
22 {
24 _algorithm = algorithm;
25 }
26 }
27
28 private static readonly long s_startOf1810 = GetNumberOfDays(new DateTime(1810, 1, 1));
29
30 private static readonly long s_startOf1900Century = GetNumberOfDays(new DateTime(1900, 1, 1));
31
32 private static readonly double[] s_coefficients1900to1987 = new double[8] { -2E-05, 0.000297, 0.025184, -0.181133, 0.55304, -0.861938, 0.677066, -0.212591 };
33
34 private static readonly double[] s_coefficients1800to1899 = new double[11]
35 {
36 -9E-06, 0.003844, 0.083563, 0.865736, 4.867575, 15.845535, 31.332267, 38.291999, 28.316289, 11.636204,
37 2.043794
38 };
39
40 private static readonly double[] s_coefficients1700to1799 = new double[4] { 8.118780842, -0.005092142, 0.003336121, -2.66484E-05 };
41
42 private static readonly double[] s_coefficients1620to1699 = new double[3] { 196.58333, -4.0675, 0.0219167 };
43
44 private static readonly double[] s_lambdaCoefficients = new double[3] { 280.46645, 36000.76983, 0.0003032 };
45
46 private static readonly double[] s_anomalyCoefficients = new double[4] { 357.5291, 35999.0503, -0.0001559, -4.8E-07 };
47
48 private static readonly double[] s_eccentricityCoefficients = new double[3] { 0.016708617, -4.2037E-05, -1.236E-07 };
49
50 private static readonly double[] s_coefficients = new double[4]
51 {
52 Angle(23, 26, 21.448),
53 Angle(0, 0, -46.815),
54 Angle(0, 0, -0.00059),
55 Angle(0, 0, 0.001813)
56 };
57
58 private static readonly double[] s_coefficientsA = new double[3] { 124.9, -1934.134, 0.002063 };
59
60 private static readonly double[] s_coefficientsB = new double[3] { 201.11, 72001.5377, 0.00057 };
61
72
73 private static double RadiansFromDegrees(double degree)
74 {
75 return degree * Math.PI / 180.0;
76 }
77
78 private static double SinOfDegree(double degree)
79 {
80 return Math.Sin(RadiansFromDegrees(degree));
81 }
82
83 private static double CosOfDegree(double degree)
84 {
85 return Math.Cos(RadiansFromDegrees(degree));
86 }
87
88 private static double TanOfDegree(double degree)
89 {
90 return Math.Tan(RadiansFromDegrees(degree));
91 }
92
93 public static double Angle(int degrees, int minutes, double seconds)
94 {
95 return (seconds / 60.0 + (double)minutes) / 60.0 + (double)degrees;
96 }
97
98 private static double Obliquity(double julianCenturies)
99 {
100 return PolynomialSum(s_coefficients, julianCenturies);
101 }
102
103 internal static long GetNumberOfDays(DateTime date)
104 {
105 return date.Ticks / 864000000000L;
106 }
107
108 private static int GetGregorianYear(double numberOfDays)
109 {
110 return new DateTime(Math.Min((long)(Math.Floor(numberOfDays) * 864000000000.0), DateTime.MaxValue.Ticks)).Year;
111 }
112
113 private static double Reminder(double divisor, double dividend)
114 {
115 double num = Math.Floor(divisor / dividend);
116 return divisor - dividend * num;
117 }
118
119 private static double NormalizeLongitude(double longitude)
120 {
121 longitude = Reminder(longitude, 360.0);
122 if (longitude < 0.0)
123 {
124 longitude += 360.0;
125 }
126 return longitude;
127 }
128
129 public static double AsDayFraction(double longitude)
130 {
131 return longitude / 360.0;
132 }
133
134 private static double PolynomialSum(double[] coefficients, double indeterminate)
135 {
136 double num = coefficients[0];
137 double num2 = 1.0;
138 for (int i = 1; i < coefficients.Length; i++)
139 {
140 num2 *= indeterminate;
141 num += coefficients[i] * num2;
142 }
143 return num;
144 }
145
146 private static double CenturiesFrom1900(int gregorianYear)
147 {
148 long numberOfDays = GetNumberOfDays(new DateTime(gregorianYear, 7, 1));
149 return (double)(numberOfDays - s_startOf1900Century) / 36525.0;
150 }
151
152 private static double DefaultEphemerisCorrection(int gregorianYear)
153 {
154 long numberOfDays = GetNumberOfDays(new DateTime(gregorianYear, 1, 1));
155 double num = numberOfDays - s_startOf1810;
156 double x = 0.5 + num;
157 return (Math.Pow(x, 2.0) / 41048480.0 - 15.0) / 86400.0;
158 }
159
160 private static double EphemerisCorrection1988to2019(int gregorianYear)
161 {
162 return (double)(gregorianYear - 1933) / 86400.0;
163 }
164
165 private static double EphemerisCorrection1900to1987(int gregorianYear)
166 {
167 double indeterminate = CenturiesFrom1900(gregorianYear);
168 return PolynomialSum(s_coefficients1900to1987, indeterminate);
169 }
170
171 private static double EphemerisCorrection1800to1899(int gregorianYear)
172 {
173 double indeterminate = CenturiesFrom1900(gregorianYear);
174 return PolynomialSum(s_coefficients1800to1899, indeterminate);
175 }
176
177 private static double EphemerisCorrection1700to1799(int gregorianYear)
178 {
179 double indeterminate = gregorianYear - 1700;
180 return PolynomialSum(s_coefficients1700to1799, indeterminate) / 86400.0;
181 }
182
183 private static double EphemerisCorrection1620to1699(int gregorianYear)
184 {
185 double indeterminate = gregorianYear - 1600;
186 return PolynomialSum(s_coefficients1620to1699, indeterminate) / 86400.0;
187 }
188
189 private static double EphemerisCorrection(double time)
190 {
191 int gregorianYear = GetGregorianYear(time);
193 for (int i = 0; i < array.Length; i++)
194 {
195 EphemerisCorrectionAlgorithmMap ephemerisCorrectionAlgorithmMap = array[i];
196 if (ephemerisCorrectionAlgorithmMap._lowestYear <= gregorianYear)
197 {
198 switch (ephemerisCorrectionAlgorithmMap._algorithm)
199 {
200 case CorrectionAlgorithm.Default:
201 return DefaultEphemerisCorrection(gregorianYear);
202 case CorrectionAlgorithm.Year1988to2019:
203 return EphemerisCorrection1988to2019(gregorianYear);
204 case CorrectionAlgorithm.Year1900to1987:
205 return EphemerisCorrection1900to1987(gregorianYear);
206 case CorrectionAlgorithm.Year1800to1899:
207 return EphemerisCorrection1800to1899(gregorianYear);
208 case CorrectionAlgorithm.Year1700to1799:
209 return EphemerisCorrection1700to1799(gregorianYear);
210 case CorrectionAlgorithm.Year1620to1699:
211 return EphemerisCorrection1620to1699(gregorianYear);
212 }
213 break;
214 }
215 }
216 return DefaultEphemerisCorrection(gregorianYear);
217 }
218
219 public static double JulianCenturies(double moment)
220 {
221 double num = moment + EphemerisCorrection(moment);
222 return (num - 730120.5) / 36525.0;
223 }
224
225 private static bool IsNegative(double value)
226 {
227 return Math.Sign(value) == -1;
228 }
229
230 private static double CopySign(double value, double sign)
231 {
232 if (IsNegative(value) != IsNegative(sign))
233 {
234 return 0.0 - value;
235 }
236 return value;
237 }
238
239 private static double EquationOfTime(double time)
240 {
241 double num = JulianCenturies(time);
242 double num2 = PolynomialSum(s_lambdaCoefficients, num);
243 double num3 = PolynomialSum(s_anomalyCoefficients, num);
244 double num4 = PolynomialSum(s_eccentricityCoefficients, num);
245 double num5 = Obliquity(num);
246 double num6 = TanOfDegree(num5 / 2.0);
247 double num7 = num6 * num6;
248 double num8 = num7 * SinOfDegree(2.0 * num2) - 2.0 * num4 * SinOfDegree(num3) + 4.0 * num4 * num7 * SinOfDegree(num3) * CosOfDegree(2.0 * num2) - 0.5 * Math.Pow(num7, 2.0) * SinOfDegree(4.0 * num2) - 1.25 * Math.Pow(num4, 2.0) * SinOfDegree(2.0 * num3);
249 double num9 = num8 / (Math.PI * 2.0);
250 return CopySign(Math.Min(Math.Abs(num9), 0.5), num9);
251 }
252
253 private static double AsLocalTime(double apparentMidday, double longitude)
254 {
255 double time = apparentMidday - AsDayFraction(longitude);
256 return apparentMidday - EquationOfTime(time);
257 }
258
259 public static double Midday(double date, double longitude)
260 {
261 return AsLocalTime(date + 0.5, longitude) - AsDayFraction(longitude);
262 }
263
264 private static double InitLongitude(double longitude)
265 {
266 return NormalizeLongitude(longitude + 180.0) - 180.0;
267 }
268
269 public static double MiddayAtPersianObservationSite(double date)
270 {
271 return Midday(date, InitLongitude(52.5));
272 }
273
274 private static double PeriodicTerm(double julianCenturies, int x, double y, double z)
275 {
276 return (double)x * SinOfDegree(y + z * julianCenturies);
277 }
278
279 private static double SumLongSequenceOfPeriodicTerms(double julianCenturies)
280 {
281 double num = 0.0;
282 num += PeriodicTerm(julianCenturies, 403406, 270.54861, 0.9287892);
283 num += PeriodicTerm(julianCenturies, 195207, 340.19128, 35999.1376958);
284 num += PeriodicTerm(julianCenturies, 119433, 63.91854, 35999.4089666);
285 num += PeriodicTerm(julianCenturies, 112392, 331.2622, 35998.7287385);
286 num += PeriodicTerm(julianCenturies, 3891, 317.843, 71998.20261);
287 num += PeriodicTerm(julianCenturies, 2819, 86.631, 71998.4403);
288 num += PeriodicTerm(julianCenturies, 1721, 240.052, 36000.35726);
289 num += PeriodicTerm(julianCenturies, 660, 310.26, 71997.4812);
290 num += PeriodicTerm(julianCenturies, 350, 247.23, 32964.4678);
291 num += PeriodicTerm(julianCenturies, 334, 260.87, -19.441);
292 num += PeriodicTerm(julianCenturies, 314, 297.82, 445267.1117);
293 num += PeriodicTerm(julianCenturies, 268, 343.14, 45036.884);
294 num += PeriodicTerm(julianCenturies, 242, 166.79, 3.1008);
295 num += PeriodicTerm(julianCenturies, 234, 81.53, 22518.4434);
296 num += PeriodicTerm(julianCenturies, 158, 3.5, -19.9739);
297 num += PeriodicTerm(julianCenturies, 132, 132.75, 65928.9345);
298 num += PeriodicTerm(julianCenturies, 129, 182.95, 9038.0293);
299 num += PeriodicTerm(julianCenturies, 114, 162.03, 3034.7684);
300 num += PeriodicTerm(julianCenturies, 99, 29.8, 33718.148);
301 num += PeriodicTerm(julianCenturies, 93, 266.4, 3034.448);
302 num += PeriodicTerm(julianCenturies, 86, 249.2, -2280.773);
303 num += PeriodicTerm(julianCenturies, 78, 157.6, 29929.992);
304 num += PeriodicTerm(julianCenturies, 72, 257.8, 31556.493);
305 num += PeriodicTerm(julianCenturies, 68, 185.1, 149.588);
306 num += PeriodicTerm(julianCenturies, 64, 69.9, 9037.75);
307 num += PeriodicTerm(julianCenturies, 46, 8.0, 107997.405);
308 num += PeriodicTerm(julianCenturies, 38, 197.1, -4444.176);
309 num += PeriodicTerm(julianCenturies, 37, 250.4, 151.771);
310 num += PeriodicTerm(julianCenturies, 32, 65.3, 67555.316);
311 num += PeriodicTerm(julianCenturies, 29, 162.7, 31556.08);
312 num += PeriodicTerm(julianCenturies, 28, 341.5, -4561.54);
313 num += PeriodicTerm(julianCenturies, 27, 291.6, 107996.706);
314 num += PeriodicTerm(julianCenturies, 27, 98.5, 1221.655);
315 num += PeriodicTerm(julianCenturies, 25, 146.7, 62894.167);
316 num += PeriodicTerm(julianCenturies, 24, 110.0, 31437.369);
317 num += PeriodicTerm(julianCenturies, 21, 5.2, 14578.298);
318 num += PeriodicTerm(julianCenturies, 21, 342.6, -31931.757);
319 num += PeriodicTerm(julianCenturies, 20, 230.9, 34777.243);
320 num += PeriodicTerm(julianCenturies, 18, 256.1, 1221.999);
321 num += PeriodicTerm(julianCenturies, 17, 45.3, 62894.511);
322 num += PeriodicTerm(julianCenturies, 14, 242.9, -4442.039);
323 num += PeriodicTerm(julianCenturies, 13, 115.2, 107997.909);
324 num += PeriodicTerm(julianCenturies, 13, 151.8, 119.066);
325 num += PeriodicTerm(julianCenturies, 13, 285.3, 16859.071);
326 num += PeriodicTerm(julianCenturies, 12, 53.3, -4.578);
327 num += PeriodicTerm(julianCenturies, 10, 126.6, 26895.292);
328 num += PeriodicTerm(julianCenturies, 10, 205.7, -39.127);
329 num += PeriodicTerm(julianCenturies, 10, 85.9, 12297.536);
330 return num + PeriodicTerm(julianCenturies, 10, 146.1, 90073.778);
331 }
332
333 private static double Aberration(double julianCenturies)
334 {
335 return 9.74E-05 * CosOfDegree(177.63 + 35999.01848 * julianCenturies) - 0.005575;
336 }
337
338 private static double Nutation(double julianCenturies)
339 {
340 double degree = PolynomialSum(s_coefficientsA, julianCenturies);
341 double degree2 = PolynomialSum(s_coefficientsB, julianCenturies);
342 return -0.004778 * SinOfDegree(degree) - 0.0003667 * SinOfDegree(degree2);
343 }
344
345 public static double Compute(double time)
346 {
347 double num = JulianCenturies(time);
348 double num2 = 282.7771834 + 36000.76953744 * num + 5.729577951308232E-06 * SumLongSequenceOfPeriodicTerms(num);
349 double longitude = num2 + Aberration(num) + Nutation(num);
350 return InitLongitude(longitude);
351 }
352
353 public static double AsSeason(double longitude)
354 {
355 if (!(longitude < 0.0))
356 {
357 return longitude;
358 }
359 return longitude + 360.0;
360 }
361
362 private static double EstimatePrior(double longitude, double time)
363 {
364 double num = time - 1.0145616361111112 * AsSeason(InitLongitude(Compute(time) - longitude));
365 double num2 = InitLongitude(Compute(num) - longitude);
366 return Math.Min(time, num - 1.0145616361111112 * num2);
367 }
368
369 internal static long PersianNewYearOnOrBefore(long numberOfDays)
370 {
371 double date = numberOfDays;
372 double d = EstimatePrior(0.0, MiddayAtPersianObservationSite(date));
373 long num = (long)Math.Floor(d) - 1;
374 long num2 = num + 3;
375 long num3;
376 for (num3 = num; num3 != num2; num3++)
377 {
378 double time = MiddayAtPersianObservationSite(num3);
379 double num4 = Compute(time);
380 if (0.0 <= num4 && num4 <= 2.0)
381 {
382 break;
383 }
384 }
385 return num3 - 1;
386 }
387}
static double EstimatePrior(double longitude, double time)
static double AsLocalTime(double apparentMidday, double longitude)
static double Angle(int degrees, int minutes, double seconds)
static readonly EphemerisCorrectionAlgorithmMap[] s_ephemerisCorrectionTable
static double Midday(double date, double longitude)
static double PolynomialSum(double[] coefficients, double indeterminate)
static double PeriodicTerm(double julianCenturies, int x, double y, double z)
static double Reminder(double divisor, double dividend)
static double SumLongSequenceOfPeriodicTerms(double julianCenturies)
static double Cos(double d)
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static double Tan(double a)
static double Pow(double x, double y)
static double Abs(double value)
static double Sin(double a)
static double Floor(double d)
static int Sign(decimal value)
Definition Math.cs:1202
static readonly DateTime MaxValue
Definition DateTime.cs:37