24
24
25
25
using System ;
26
26
using Microsoft . Xna . Framework ;
27
+ using Orts . Formats . Msts ;
27
28
28
29
namespace Orts . Viewer3D . Common
29
30
{
@@ -35,26 +36,18 @@ static class SunMoonPos
35
36
/// </summary>
36
37
/// <param name="latitude">Latitude, radians.</param>
37
38
/// <param name="longitude">Longitude, radians.</param>
39
+ /// <param name="sun">Sun satellite information (including rise/set time).</param>
38
40
/// <param name="clockTime">Wall clock time since start of activity, days.</param>
39
41
/// <param name="date">Structure made up of day, month, year and ordinal date.</param>
40
42
/// <returns>A normalize 3D vector indicating the sun's position from the viewer's location.</returns>
41
- public static Vector3 SolarAngle ( double latitude , double longitude , float clockTime , SkyViewer . SkyDate date )
43
+ public static Vector3 SolarAngle ( double latitude , double longitude , EnvironmentFile . SkySatellite sun , float clockTime , SkyViewer . SkyDate date )
42
44
{
43
45
Vector3 sunDirection ;
44
-
45
- // For these calculations, west longitude is in positive degrees
46
- var noaaLongitude = - MathHelper . ToDegrees ( ( float ) longitude ) ;
46
+ double solarHourAngle ;
47
47
48
48
// Fractional year, radians
49
49
var fYear = ( MathHelper . TwoPi / 365 ) * ( date . OrdinalDate - 1 + ( clockTime - 0.5 ) ) ;
50
50
51
- // Equation of time, minutes
52
- var eqTime = 229.18 * ( 0.000075
53
- + ( 0.001868 * Math . Cos ( fYear ) )
54
- - ( 0.032077 * Math . Sin ( fYear ) )
55
- - ( 0.014615 * Math . Cos ( 2 * fYear ) )
56
- - ( 0.040849 * Math . Sin ( 2 * fYear ) ) ) ;
57
-
58
51
// Solar declination, radians
59
52
var solarDeclination = 0.006918
60
53
- ( 0.399912 * Math . Cos ( fYear ) )
@@ -64,14 +57,37 @@ public static Vector3 SolarAngle(double latitude, double longitude, float clockT
64
57
- ( 0.002697 * Math . Cos ( 3 * fYear ) )
65
58
+ ( 0.001480 * Math . Sin ( 3 * fYear ) ) ;
66
59
67
- // Time offset at present longitude, minutes
68
- var timeOffset = eqTime - ( 4 * noaaLongitude ) + ( 60 * Math . Round ( noaaLongitude / 15 ) ) ;
60
+ // How much the latitude and solar declination changes the horizon so that we can correctly calculate
61
+ // the solar angle based on sun rise/set times
62
+ var horizonSolarHourAngle = Math . Acos ( - ( Math . Sin ( latitude ) * Math . Sin ( solarDeclination ) ) / ( Math . Cos ( latitude ) * Math . Cos ( solarDeclination ) ) ) ;
69
63
70
- // True solar time, minutes (since midnight)
71
- var trueSolar = ( clockTime * 24 * 60 ) + timeOffset ;
64
+ if ( sun ? . RiseTime != 0 && sun ? . SetTime != 0 && sun ? . RiseTime < sun ? . SetTime && ! double . IsNaN ( horizonSolarHourAngle ) )
65
+ {
66
+ var noonTimeD = ( float ) ( sun . RiseTime + sun . SetTime ) / 2 / 86400 ;
67
+ var riseSetScale = 90 / ( noonTimeD - ( ( float ) sun . RiseTime / 86400 ) ) ;
68
+ solarHourAngle = MathHelper . ToRadians ( ( clockTime - noonTimeD ) * riseSetScale * ( float ) ( horizonSolarHourAngle / MathHelper . PiOver2 ) ) ;
69
+ }
70
+ else
71
+ {
72
+ // For these calculations, west longitude is in positive degrees
73
+ var noaaLongitude = - MathHelper . ToDegrees ( ( float ) longitude ) ;
72
74
73
- // Solar hour angle, radians
74
- var solarHourAngle = MathHelper . ToRadians ( ( float ) ( trueSolar / 4 ) - 180 ) ;
75
+ // Equation of time, minutes
76
+ var eqTime = 229.18 * ( 0.000075
77
+ + ( 0.001868 * Math . Cos ( fYear ) )
78
+ - ( 0.032077 * Math . Sin ( fYear ) )
79
+ - ( 0.014615 * Math . Cos ( 2 * fYear ) )
80
+ - ( 0.040849 * Math . Sin ( 2 * fYear ) ) ) ;
81
+
82
+ // Time offset at present longitude, minutes
83
+ var timeOffset = eqTime - ( 4 * noaaLongitude ) + ( 60 * Math . Round ( noaaLongitude / 15 ) ) ;
84
+
85
+ // True solar time, minutes (since midnight)
86
+ var trueSolar = ( clockTime * 24 * 60 ) + timeOffset ;
87
+
88
+ // Solar hour angle, radians
89
+ solarHourAngle = MathHelper . ToRadians ( ( float ) ( trueSolar / 4 ) - 180 ) ;
90
+ }
75
91
76
92
// Solar zenith cosine. This is the Y COORDINATE of the solar Vector.
77
93
var solarZenithCosine = ( Math . Sin ( latitude ) * Math . Sin ( solarDeclination ) )
0 commit comments