static int Main(string[] args) { var bodies = new Body[] { Body.Sun, Body.Moon, Body.Mercury, Body.Venus, Body.Mars, Body.Jupiter, Body.Saturn, Body.Uranus, Body.Neptune, Body.Pluto }; Observer observer; AstroTime time; DemoHelper.ParseArgs("positions", args, out observer, out time); Console.WriteLine("UTC date = {0}", time); Console.WriteLine(); Console.WriteLine("BODY RA DEC AZ ALT"); foreach (Body body in bodies) { Equatorial equ_2000 = Astronomy.Equator(body, time, observer, EquatorEpoch.J2000, Aberration.Corrected); Equatorial equ_ofdate = Astronomy.Equator(body, time, observer, EquatorEpoch.OfDate, Aberration.Corrected); Topocentric hor = Astronomy.Horizon(time, observer, equ_ofdate.ra, equ_ofdate.dec, Refraction.Normal); Console.WriteLine("{0,-8} {1,8:0.00} {2,8:0.00} {3,8:0.00} {4,8:0.00}", body, equ_2000.ra, equ_2000.dec, hor.azimuth, hor.altitude); } return(0); }
public void Astronomy_HasOneSunsets_Should_ReturnCorrectSunset() { // Arrange var astro = new Astronomy(); var events = new List <AstronomyEvent> (); var sunrise = new AstronomyEvent { Type = AstronomyEventType.Rise, Time = new DateTime().AddHours(1).AddMinutes(58) }; var sunset = new AstronomyEvent { Type = AstronomyEventType.Set, Time = new DateTime().AddHours(0).AddMinutes(3) }; events.Add(sunrise); events.Add(sunset); astro.Events = events; // Act var set = astro.Sunset; // Assert Assert.AreEqual(sunset.Time.Hour, set.Value.Hour); Assert.AreEqual(sunset.Time.Minute, set.Value.Minute); }
static int Intersect(AstroVector pos1, AstroVector dir1, AstroVector pos2, AstroVector dir2) { double F = dir1 * dir2; AstroVector amb = pos1 - pos2; double E = dir1 * amb; double G = dir2 * amb; double denom = 1.0 - F * F; if (denom == 0.0) { Console.WriteLine("ERROR: Cannot solve because directions are parallel."); return(1); } double u = (F * G - E) / denom; double v = G + F * u; if (u < 0.0 || v < 0.0) { Console.WriteLine("ERROR: Lines of sight do not converge."); return(1); } AstroVector a = pos1 + u * dir1; AstroVector b = pos2 + v * dir2; AstroVector c = (a + b) / 2.0; AstroVector miss = a - b; double dist = (Astronomy.KM_PER_AU * 1000 / 2) * miss.Length(); // error radius in meters Observer obs = Astronomy.VectorObserver(c, EquatorEpoch.OfDate); Console.WriteLine($"Solution: lat = {obs.latitude:F6}, lon = {obs.longitude:F6}, elv = {obs.height:F3} meters; error = {dist:F3} meters."); return(0); }
static int Main(string[] args) { Observer observer; AstroTime time; DemoHelper.ParseArgs("riseset", args, out observer, out time); Console.WriteLine("search : {0}", time); if (0 != PrintEvent("sunrise", Astronomy.SearchRiseSet(Body.Sun, observer, Direction.Rise, time, 300.0))) { return(1); } if (0 != PrintEvent("sunset", Astronomy.SearchRiseSet(Body.Sun, observer, Direction.Set, time, 300.0))) { return(1); } if (0 != PrintEvent("moonrise", Astronomy.SearchRiseSet(Body.Moon, observer, Direction.Rise, time, 300.0))) { return(1); } if (0 != PrintEvent("moonset", Astronomy.SearchRiseSet(Body.Moon, observer, Direction.Set, time, 300.0))) { return(1); } return(0); }
static int Main(string[] args) { if (args.Length != 2) { Console.WriteLine("{0}", UsageText); return(1); } const double MAX_HEIGHT_METERS = 100000.0; // Force use of "." for the decimal mark, regardless of local culture settings. Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; double latitude = double.Parse(args[0]); if (!double.IsFinite(latitude) || latitude < -90.0 || latitude > +90.0) { Console.WriteLine($"ERROR: Invalid latitude '{args[0]}'. Must be a number between -90 and +90."); return(1); } double height = double.Parse(args[1]); if (!double.IsFinite(height) || height < 0.0 || height > MAX_HEIGHT_METERS) { Console.WriteLine($"ERROR: Invalid height '{args[1]}'. Must be a number between 0 and {MAX_HEIGHT_METERS:F0}."); return(1); } double gravity = Astronomy.ObserverGravity(latitude, height); Console.WriteLine($"latitude = {latitude,8:F4}, height = {height,6:F0}, gravity = {gravity,8:F6}"); return(0); }
public void CalculateSunsetTime_Test(GeoLocation location, DateTimeOffset instant, TimeSpan expectedSunsetTime) { // Act var sunsetTime = Astronomy.CalculateSunsetTime(location, instant); // Assert Assert.That(sunsetTime, Is.EqualTo(expectedSunsetTime).Within(TimeSpan.FromMinutes(3))); }
public CopernicusObservatory() : base(30) { Name = "Copernicus' Observatory"; RequiredTech = new Astronomy(); ObsoleteTech = new Automobile(); SetSmallIcon(6, 0); Type = Wonder.CopernicusObservatory; }
public override void Update() { Astronomy.Update(); Weather.Update(); m_PathPositions.Add(Astronomy.Orbit); m_UpdateInterval = 0; if (m_UpdateInterval > 0) { m_UpdateTimer += Time.deltaTime; if (m_UpdateTimer < m_UpdateInterval) { return; } m_UpdateTimer = 0; } //UPDATE GLOABL ENVIRONMENT INFOS // TEMPERATURE TemperatureScale = Weather.TemperatureScale; Temperature = Weather.Temperature; MinTemperature = Weather.MinTemperature; MaxTemperature = Weather.MaxTemperature; // DATE & TIME TimeHour = (int)Astronomy.Hour; TimeMinutes = (int)Astronomy.Minutes; TimeSeconds = (int)Astronomy.Seconds; DateDay = (int)Astronomy.Day; DateMonth = (int)Astronomy.Month; DateYear = (int)Astronomy.Year; // ASTRO if (Display.UITextDateTime != null) { Display.UITextDateTime.text = CurrentDateTimeString; } if (Display.UITextDay != null) { Display.UITextDay.text = string.Format(Display.UITextDayFormat, Astronomy.DayTotal + (Display.UseFirstDay ? 1 : 0)); } // WEATHER if (Display.UITemperatur != null) { Display.UITemperatur.text = string.Format(Display.UITemperaturFormat, Mathf.RoundToInt(Weather.Temperature)); } // LIGHT LightIntensity = Astronomy.SunLightIntensity; }
public static double SunHoursToRadiations(this double sunHours, DateTime date, ILocation position) { int dayOfYear = Astronomy.DayOfYear(date); double dayAngle = Astronomy.DayAngle(date); double latitude = Astronomy.BoundedLatitude(position); double solarDeclination = Astronomy.SolarDeclination(dayOfYear); double daylightTimeFactor = Astronomy.DaylightTimeFactor(latitude, solarDeclination); double solarDistanceCorrection = Astronomy.SolarDistanceCorrection(dayAngle); double num = Astronomy.DayLength(daylightTimeFactor); return(Math.Max(0.1, Astronomy.ExtraTerrestrialRadiation(latitude, solarDistanceCorrection, solarDeclination, daylightTimeFactor) * (0.1 + 0.24 * sunHours / num + (0.78 - 0.44 * sunHours / num) * sunHours / num))); }
static AstroVector DirectionVector(AstroTime time, Observer observer, double altitude, double azimuth) { // Convert horizontal angles to a horizontal unit vector. var hor = new Spherical(altitude, azimuth, 1.0); AstroVector hvec = Astronomy.VectorFromHorizon(hor, time, Refraction.None); // Find the rotation matrix that converts horizontal vectors to equatorial vectors. RotationMatrix rot = Astronomy.Rotation_HOR_EQD(time, observer); // Rotate the horizontal (HOR) vector to an equator-of-date (EQD) vector. AstroVector evec = Astronomy.RotateVector(rot, hvec); return(evec); }
static int Main(string[] args) { AstroTime time; switch (args.Length) { case 0: time = new AstroTime(DateTime.Now); break; case 1: time = DemoHelper.ParseTime("moonphase", args[0]); break; default: Console.WriteLine("USAGE: moonphase [date]"); return(1); } /* * Calculate the Moon's current phase angle, * which ranges from 0 to 360 degrees. * * 0 = new moon, * 90 = first quarter, * 180 = full moon, * 270 = third quarter. */ double phase = Astronomy.MoonPhase(time); Console.WriteLine("{0} : Moon's phase angle = {1:0.000000} degrees.", time, phase); /* Find the next 10 lunar quarter phases. */ Console.WriteLine(); Console.WriteLine("The next 10 lunar quarters are:"); MoonQuarterInfo mq = Astronomy.SearchMoonQuarter(time); for (int i = 0; i < 10; ++i) { if (i > 0) { mq = Astronomy.NextMoonQuarter(mq); } Console.WriteLine("{0} : {1}", mq.time, QuarterName(mq.quarter)); } return(0); }
/// <summary> /// Get sunrise, sunset. /// </summary> /// <returns></returns> protected IAstronomy GetSunInfo(DateTime?utcDate, CancellationToken token) { if (IfCancellationRequested(token) || !utcDate.HasValue || !Latitude.HasValue || !Longitude.HasValue) { return(null); } var sunInfo = GetSunInfo(utcDate.Value, token); if (sunInfo?.Validate() != true) { return(null); } var result = new Astronomy { Sunrise = sunInfo.Sunrise, Sunset = sunInfo.Sunset }; if (utcDate < sunInfo.Sunrise) { var sunInfoPrevious = GetSunInfo(utcDate.Value.AddDays(-1), token); if (sunInfoPrevious?.Validate() == true) { result.PreviousInfo = new AstronomyInfo { Sunrise = sunInfoPrevious.Sunrise, Sunset = sunInfoPrevious.Sunset }; } } else if (utcDate > sunInfo.Sunset) { var sunInfoNext = GetSunInfo(utcDate.Value.AddDays(1), token); if (sunInfoNext?.Validate() == true) { result.PreviousInfo = new AstronomyInfo { Sunrise = sunInfoNext.Sunrise, Sunset = sunInfoNext.Sunset }; } } return(result); }
static int Main(string[] args) { int year; if (args.Length != 1 || !int.TryParse(args[0], out year) || year <Astronomy.MinYear || year> Astronomy.MaxYear) { Console.WriteLine("ERROR: Must provide year {0}..{1} on command line.", Astronomy.MinYear, Astronomy.MaxYear); return(1); } SeasonsInfo seasons = Astronomy.Seasons(year); Console.WriteLine("March equinox : {0}", seasons.mar_equinox); Console.WriteLine("June solstice : {0}", seasons.jun_solstice); Console.WriteLine("September equinox : {0}", seasons.sep_equinox); Console.WriteLine("December solstice : {0}", seasons.dec_solstice); return(0); }
private void OnDrawGizmos() { if (Astronomy.SunLight == null) { return; } if (!Application.isPlaying) { Astronomy.SunLight.transform.localRotation = Astronomy.Rotation(); } Gizmos.color = Color.blue; Gizmos.DrawLine(Astronomy.SunLight.transform.position + (Astronomy.SunLight.transform.forward * Astronomy.Radius * 0.75f), Astronomy.SunLight.transform.position + (Astronomy.SunLight.transform.forward * Astronomy.Radius)); //Gizmos.DrawLine( Sun.transform.position - ( Sun.transform.forward * Radius * 0.75f ), Sun.transform.position - ( Sun.transform.forward * Radius ) ); CustomGizmos.Circle(Astronomy.SunLight.transform.position, Astronomy.SunLight.transform.up, Astronomy.Radius); CustomGizmos.Arrow(Astronomy.SunLight.transform.position + (Astronomy.SunLight.transform.forward * Astronomy.Radius * 0.75f), Astronomy.SunLight.transform.forward * -2, 10); CustomGizmos.HandlesColor(Gizmos.color); CustomGizmos.Arrow(0, Astronomy.SunLight.transform.position - (Astronomy.SunLight.transform.forward * Astronomy.Radius), Astronomy.SunLight.transform.rotation, 50); if (m_PathPositions.Count > 1000) { m_PathPositions.RemoveAt(0); } Vector3 _prior_pos = Vector3.zero; foreach (Vector3 _pos in m_PathPositions) { if (_prior_pos != Vector3.zero) { Gizmos.DrawLine(_prior_pos, _pos); } _prior_pos = _pos; } }
static int Main(string[] args) { Observer observer; AstroTime time; DemoHelper.ParseArgs("culminate", args, out observer, out time); var bodies = new Body[] { Body.Sun, Body.Moon, Body.Mercury, Body.Venus, Body.Mars, Body.Jupiter, Body.Saturn, Body.Uranus, Body.Neptune, Body.Pluto }; Console.WriteLine("search : {0}", time); foreach (Body body in bodies) { HourAngleInfo evt = Astronomy.SearchHourAngle(body, observer, 0.0, time); Console.WriteLine("{0,-8} : {1} altitude={2:##0.00} azimuth={3:##0.00}", body, evt.time, evt.hor.altitude, evt.hor.azimuth); } return(0); }
static int HorizontalCoords( out Spherical hor, double ecliptic_longitude, AstroTime time, RotationMatrix rot_ecl_hor) { var eclip = new Spherical( 0.0, /* being "on the ecliptic plane" means ecliptic latitude is zero. */ ecliptic_longitude, 1.0 /* any positive distance value will work fine. */ ); /* Convert ecliptic angular coordinates to ecliptic vector. */ AstroVector ecl_vec = Astronomy.VectorFromSphere(eclip, time); /* Use the rotation matrix to convert ecliptic vector to horizontal vector. */ AstroVector hor_vec = Astronomy.RotateVector(rot_ecl_hor, ecl_vec); /* Find horizontal angular coordinates, correcting for atmospheric refraction. */ hor = Astronomy.HorizonFromVector(hor_vec, Refraction.Normal); return(0); /* success */ }
static int Main(string[] args) { if (args.Length != 10) { Console.WriteLine(UsageText); return(1); } // Validate and parse command line arguments. double lat1 = ParseNumber("lat1", args[0]); double lon1 = ParseNumber("lon1", args[1]); double elv1 = ParseNumber("elv1", args[2]); double az1 = ParseNumber("az1", args[3]); double alt1 = ParseNumber("alt1", args[4]); double lat2 = ParseNumber("lat2", args[5]); double lon2 = ParseNumber("lon2", args[6]); double elv2 = ParseNumber("elv2", args[7]); double az2 = ParseNumber("az2", args[8]); double alt2 = ParseNumber("alt2", args[9]); var obs1 = new Observer(lat1, lon1, elv1); var obs2 = new Observer(lat2, lon2, elv2); // Use an arbitrary but consistent time for the Earth's rotation. AstroTime time = new AstroTime(0.0); // Convert geographic coordinates of the observers to vectors. AstroVector pos1 = Astronomy.ObserverVector(time, obs1, EquatorEpoch.OfDate); AstroVector pos2 = Astronomy.ObserverVector(time, obs2, EquatorEpoch.OfDate); // Convert horizontal coordinates into unit direction vectors. AstroVector dir1 = DirectionVector(time, obs1, alt1, az1); AstroVector dir2 = DirectionVector(time, obs2, alt2, az2); // Find the closest point between the skew lines. return(Intersect(pos1, dir1, pos2, dir2)); }
static int Main(string[] args) { AstroTime time; switch (args.Length) { case 0: time = new AstroTime(DateTime.Now); break; case 1: time = DemoHelper.ParseTime("lunar_eclipse", args[0]); break; default: Console.WriteLine("USAGE: lunar_eclipse [date]"); return(1); } int count = 0; LunarEclipseInfo eclipse = Astronomy.SearchLunarEclipse(time); for (;;) { if (eclipse.kind != EclipseKind.Penumbral) { PrintEclipse(eclipse); if (++count == 10) { break; } } eclipse = Astronomy.NextLunarEclipse(eclipse.peak); } return(0); }
public override void Start() { Display.Init(this); Astronomy.Init(this); Weather.Init(this); }
public override void FixedUpdate() { Astronomy.FixedUpdate(); }
private void BuildAstro() => this.astro = new Astronomy();
static int CameraImage(Observer observer, AstroTime time) { const double tolerance = 1.0e-15; // Calculate the topocentric equatorial coordinates of date for the Moon. // Assume aberration does not matter because the Moon is so close and has such a small relative velocity. Equatorial moon_equ = Astronomy.Equator(Body.Moon, time, observer, EquatorEpoch.OfDate, Aberration.None); // Also calculate the Sun's topocentric position in the same coordinate system. Equatorial sun_equ = Astronomy.Equator(Body.Sun, time, observer, EquatorEpoch.OfDate, Aberration.None); // Get the Moon's horizontal coordinates, so we know how much to pivot azimuth and altitude. Topocentric moon_hor = Astronomy.Horizon(time, observer, moon_equ.ra, moon_equ.dec, Refraction.None); Console.WriteLine($"Moon horizontal position: azimuth = {moon_hor.azimuth:F3}, altitude = {moon_hor.altitude:F3}"); // Get the rotation matrix that converts equatorial to horizontal coordintes for this place and time. RotationMatrix rot = Astronomy.Rotation_EQD_HOR(time, observer); // Modify the rotation matrix in two steps: // First, rotate the orientation so we are facing the Moon's azimuth. // We do this by pivoting around the zenith axis. // Horizontal axes are: 0 = north, 1 = west, 2 = zenith. // Tricky: because the pivot angle increases counterclockwise, and azimuth // increases clockwise, we undo the azimuth by adding the positive value. rot = Astronomy.Pivot(rot, 2, moon_hor.azimuth); // Second, pivot around the leftward axis to bring the Moon to the camera's altitude level. // From the point of view of the leftward axis, looking toward the camera, // adding the angle is the correct sense for subtracting the altitude. rot = Astronomy.Pivot(rot, 1, moon_hor.altitude); // As a sanity check, apply this rotation to the Moon's equatorial (EQD) coordinates and verify x=0, y=0. AstroVector vec = Astronomy.RotateVector(rot, moon_equ.vec); // Convert to unit vector. double radius = vec.Length(); vec.x /= radius; vec.y /= radius; vec.z /= radius; Console.WriteLine($"Moon check: x = {vec.x}, y = {vec.y}, z = {vec.z}"); if (!double.IsFinite(vec.x) || Math.Abs(vec.x - 1.0) > tolerance) { Console.WriteLine("Excessive error in moon check (x)."); return(1); } if (!double.IsFinite(vec.y) || Math.Abs(vec.y) > tolerance) { Console.WriteLine("Excessive error in moon check (y)."); return(1); } if (!double.IsFinite(vec.z) || Math.Abs(vec.z) > tolerance) { Console.WriteLine("Excessive error in moon check (z)."); return(1); } // Apply the same rotation to the Sun's equatorial vector. // The x- and y-coordinates now tell us which side appears sunlit in the camera! vec = Astronomy.RotateVector(rot, sun_equ.vec); // Don't bother normalizing the Sun vector, because in AU it will be close to unit anyway. Console.WriteLine($"Sun vector: x = {vec.x:F6}, y = {vec.y:F6}, z = {vec.z:F6}"); // Calculate the tilt angle of the sunlit side, as seen by the camera. // The x-axis is now pointing directly at the object, z is up in the camera image, y is to the left. double tilt = RAD2DEG * Math.Atan2(vec.z, vec.y); Console.WriteLine($"Tilt angle of sunlit side of the Moon = {tilt:F3} degrees counterclockwise from up."); IllumInfo illum = Astronomy.Illumination(Body.Moon, time); Console.WriteLine($"Moon magnitude = {illum.mag:F2}, phase angle = {illum.phase_angle:F2} degrees."); double angle = Astronomy.AngleFromSun(Body.Moon, time); Console.WriteLine($"Angle between Moon and Sun as seen from Earth = {angle:F2} degrees."); return(0); }
static int FindEclipticCrossings(Observer observer, AstroTime time) { int i; var hor = new Spherical[NUM_SAMPLES]; /* * The ecliptic is a celestial circle that describes the mean plane of * the Earth's orbit around the Sun. We use J2000 ecliptic coordinates, * meaning the x-axis is defined to where the plane of the Earth's * equator on January 1, 2000 at noon UTC intersects the ecliptic plane. * The positive x-axis points toward the March equinox. * Calculate a rotation matrix that converts J2000 ecliptic vectors * to horizontal vectors for this observer and time. */ RotationMatrix rot = Astronomy.Rotation_ECL_HOR(time, observer); /* * Sample several points around the ecliptic. * Remember the horizontal coordinates for each sample. */ for (i = 0; i < NUM_SAMPLES; ++i) { if (0 != HorizontalCoords(out hor[i], ECLIPLON(i), time, rot)) { return(1); /* failure */ } } for (i = 0; i < NUM_SAMPLES; ++i) { double a1 = hor[i].lat; double a2 = hor[(i + 1) % NUM_SAMPLES].lat; double e1 = ECLIPLON(i); double e2 = ECLIPLON(i + 1); double ex; Spherical hx; int error; if (a1 * a2 <= 0.0) { /* Looks like a horizon crossing. Is altitude going up with longitude or down? */ if (a2 > a1) { /* Search for the ecliptic longitude and azimuth where altitude ascends through zero. */ error = Search(out ex, out hx, time, rot, e1, e2); } else { /* Search for the ecliptic longitude and azimuth where altitude descends through zero. */ error = Search(out ex, out hx, time, rot, e2, e1); } if (error != 0) { return(error); } string direction; if (hx.lon > 0.0 && hx.lon < 180.0) { direction = "ascends "; /* azimuth is more toward the east than the west */ } else { direction = "descends"; /* azimuth is more toward the west than the east */ } Console.WriteLine("Ecliptic longitude {0,9:0.0000} {1} through horizon az {2,9:0.0000}, alt {3,12:0.000e+00}", ex, direction, hx.lon, hx.lat); } } return(0); }