public Promise Play() { introDeferred = Deferred.Create(); SpaceTime.QueueAction("GameIntro", PlaySceneInternal); SpaceTime.Start("PowerArgsGameIntro"); return(introDeferred.Promise); }
public Promise Play() { introDeferred = Deferred.Create(); SpaceTime.QueueAction(PlaySceneInternal); SpaceTime.Start(); return(introDeferred.Promise); }
public async Task TestSpaceTimeAsynchronousExceptionDoASAPInFinally() { var message = "Plain old Exception"; var st = new SpaceTime(80, 40); st.Invoke(async() => { try { await TaskEx.WhenAny(Task.Delay(100), Task.Delay(10)); } finally { throw new Exception(message); } }); bool handled = false; try { await st.Start(); }catch (Exception exc) { var ex = exc.Clean().Single(); Assert.AreEqual(message, ex.Message); handled = true; } Assert.IsTrue(handled); }
public Task Play() { introDeferred = new TaskCompletionSource <bool>(); SpaceTime.InvokeNextCycle(PlaySceneInternal); SpaceTime.Start(); return(introDeferred.Task); }
private void ListenForCharacterNearRightEdge() { SpaceTime.Invoke(async() => { while (SpaceTime.IsRunning) { if (character.Left > Width - 2) { // turn the character around so he now moves to the left character.Velocity.Speed = 8; character.Velocity.Angle = 180; // drop a timed mine var dropper = new TimedMineDropper() { Delay = TimeSpan.FromSeconds(4), AmmoAmount = 1, Holder = character }; dropper.Exploded.SubscribeOnce(() => Sound.Play("PowerArgsIntro")); dropper.FireInternal(false); // eventually he will hit the left wall, remove him when that happens character.Velocity.ImpactOccurred.SubscribeForLifetime((i) => character.Lifetime.Dispose(), character.Lifetime); // this watcher has done its job, stop watching the secne break; } await SpaceTime.YieldAsync(); } }); }
private void ListenForCharacterNearRightEdge() { ITimeFunction watcher = null; watcher = TimeFunction.Create(() => { if (character.Left > Width - 2) { // turn the character around so he now moves to the left character.Speed.SpeedX = -8; // drop a timed mine var dropper = new TimedMineDropper() { Delay = TimeSpan.FromSeconds(4), AmmoAmount = 1, Holder = character }; dropper.Exploded.SubscribeOnce(() => Sound.Play("PowerArgsIntro")); dropper.FireInternal(); // eventually he will hit the left wall, remove him when that happens character.Speed.ImpactOccurred.SubscribeForLifetime((i) => character.Lifetime.Dispose(), character.Lifetime); // this watcher has done its job, stop watching the secne watcher.Lifetime.Dispose(); } }); SpaceTime.Add(watcher); }
public static Sun SolarPA(SpaceTime spaceTime) { SPA.SPAData spa = new SPA.SPAData { Year = spaceTime.Year, Month = spaceTime.Month, Day = spaceTime.Day, Hour = spaceTime.Hour, Minute = spaceTime.Minute, Second = spaceTime.Second, Timezone = spaceTime.Location.UtcOffset, DeltaUt1 = 0, DeltaT = 67, Longitude = spaceTime.Location.Longitude, Latitude = spaceTime.Location.Latitude, Elevation = spaceTime.Location.Elevation, Pressure = 820, Temperature = 11, Slope = 0, AzmRotation = 0, AtmosRefract = 0.5667, Function = SPA.CalculationMode.SPA_ALL }; var result = SPA.SPACalculate(ref spa); return(new Sun { Altitude = 90 - spa.Zenith, Azimuth = spa.Azimuth, Sunrise = spa.Sunrise, Sunset = spa.Sunset }); }
/***************************************************/ /**** Public Methods ****/ /***************************************************/ /*[Description("DailyPath")] * [Input("sun", "Sun position")] * [Output("SolarVector", "The sun vector calculated position")] * public static Circle DailyPath(this SpaceTime spaceTime) * { * double[] hours = { 0, 11.9, 12 }; * List<Point> sunPositions = new List<Point>(); * bool validCircle = false; * * foreach (double hour in hours) * { * int h = (int)hour; * int m = (int)(hour - (double)h) * 60; * spaceTime.Hour = h; * spaceTime.Minute = m; * Sun sun = spaceTime.SolarPosition(); * * Point sunPosition = Geometry.Create.Point(sun.SolarVector()); * sunPositions.Add(sunPosition); * if (sunPosition.Z > 0) * validCircle = true; * } * * if (validCircle) * { * * Circle circle = Geometry.Create.Circle(sunPositions[0], sunPositions[1], sunPositions[2]); * return circle; * } * Circle circlea = new Circle(); * return circlea; * * } * * public static ICurve DailyPath(SpaceTime spaceTime) * { * * List<Point> sunPositions = new List<Point>(); * bool isCircle = false; * * Sun sun = SolarPA(spaceTime); * if (sun.Sunrise < 0) * { * isCircle = true; * sun.Sunrise = 0.1; * sun.Sunset = 23.9; * } * double midday = (sun.Sunset - sun.Sunrise)/ 2 + sun.Sunrise; * double[] hours = { sun.Sunset, midday, sun.Sunrise }; * * foreach (double hour in hours) * { * TimeSpan time = TimeSpan.FromHours(hour); * spaceTime.Hour = time.Hours; * spaceTime.Minute = time.Minutes; * spaceTime.Second = time.Seconds; * spaceTime.Millisecond = time.Milliseconds; * * Sun ssun = SolarPA(spaceTime); * * Point sunPosition = Geometry.Create.Point(ssun.SolarVector()); * sunPositions.Add(sunPosition); * } * * if (isCircle) * { * Circle circle = Geometry.Create.Circle(sunPositions[0], sunPositions[1], sunPositions[2]); * return circle; * } * else * { * Arc arc = Geometry.Create.Arc(sunPositions[0], sunPositions[1], sunPositions[2]); * return arc; * } * * } * */ public static ICurve DailyPath(this SpaceTime spaceTime) { double[] hours = { 0, 11.9, 12 }; List <Point> sunPositions = new List <Point>(); bool validCircle = false; foreach (double hour in hours) { TimeSpan time = TimeSpan.FromHours(hour); spaceTime.Hour = time.Hours; spaceTime.Minute = time.Minutes; spaceTime.Second = time.Seconds; spaceTime.Millisecond = time.Milliseconds; Sun sun = SolarPA(spaceTime); Point sunPosition = Geometry.Create.Point(sun.SolarVector()); sunPositions.Add(sunPosition); if (sunPosition.Z > 0) { validCircle = true; } } if (validCircle) { Circle circle = Geometry.Create.Circle(sunPositions[0], sunPositions[1], sunPositions[2]); return(circle); } Circle circlea = new Circle(); return(circlea); }
public async Task TestSpaceTimeAsynchronousExceptionQueueAction() { using (var lt = new Lifetime()) { var message = "Plain old Exception"; var st = new SpaceTime(80, 40); st.InvokeNextCycle(async() => { await Task.Yield(); throw new Exception(message); }); bool handled = false; try { await st.Start(); }catch (Exception exc) { var ex = exc.Clean().Single(); Assert.AreEqual(message, ex.Message); handled = true; } Assert.IsTrue(handled); } }
public static List <ICurve> HourPath(SpaceTime spaceTime) { List <ICurve> paths = new List <ICurve>(); for (int h = 0; h <= 23; ++h) { List <Point3d> sunPositions = new List <Point3d>(); for (int m = 1; m <= 12; ++m) { spaceTime.Day = 21; spaceTime.Month = m; spaceTime.Hour = h; Sun ss = SolarPA(spaceTime); Point sunPosition = Geometry.Create.Point(ss.SolarVector()); Point3d sunPosition3d = Rhinoceros.Convert.ToRhino(sunPosition); sunPositions.Add(sunPosition3d); } sunPositions.Add(sunPositions[0]); Rhino.Geometry.CurveKnotStyle nnotStyle = Rhino.Geometry.CurveKnotStyle.UniformPeriodic; Curve crv = Curve.CreateInterpolatedCurve(sunPositions, 3, nnotStyle); ICurve crvB = Rhinoceros.Convert.ToBHoM(crv); paths.Add(crvB); } return(paths); }
public static void generateVideoForEvaluation(List <Image> Images, List <DateTime> dateTimeList, MultiObjectTrackingResult ctts, String videoName, String directory) { List <Image> imagesWithTracks = new List <Image>(); for (int i = 0; i < Images.Count; i++) { List <BoundingBox> locations = new List <BoundingBox>(); List <string> labels = new List <string>(); Dictionary <string, List <bool> > attributes = new Dictionary <string, List <bool> >(); attributes.Add("occlusion", new List <bool>()); if (ctts.tracks.Count != 0) { foreach (string key in ctts.tracks[0].booleanAttributeTracks.Keys) { if (!attributes.ContainsKey(key)) { attributes.Add(key, new List <bool>()); } } } List <int> idx = new List <int>(); for (int j = 0; j < ctts.tracks.Count; j++) { CompressedTrack ct = ctts.tracks[j]; SpaceTime st = ct.getSpaceTimeAt(dateTimeList[i]); BooleanAttribute outofview_attr = ct.getAttributeAt("outofview", dateTimeList[i]); if (st != null && outofview_attr != null && !outofview_attr.value) { BoundingBox l = st.region; locations.Add(l); labels.Add(ctts.tracks[j].label); foreach (string key in attributes.Keys) { attributes[key].Add(ct.getAttributeAt(key, dateTimeList[i]).value); } idx.Add(j); } } Image new_image = generateTrackImage(Images[i], labels, locations, attributes, idx); imagesWithTracks.Add(new_image); } Console.WriteLine("Saving " + directory + "\\" + videoName); FFMpegWrappers.generateVideoFromFrames(imagesWithTracks, videoName, directory); //Directory.CreateDirectory(directory + "\\" + videoName); //Console.WriteLine("Saving " + directory + "\\" + videoName); //for (int i = 0; i < imagesWithTracks.Count; i++) //{ // imagesWithTracks[i].Save(directory + "\\" + videoName + "\\img" + i.ToString("000") + ".jpg"); //} //Console.WriteLine("done"); }
public static DateTime DateTime(this SpaceTime spaceTime) { if (spaceTime == null) { BH.Engine.Reflection.Compute.RecordError("Cannot query the date/time of a null space time object."); return(System.DateTime.Now); } return(spaceTime.Time.DateTime()); }
private void ListenForEndOfIntro() { SpaceTime.Add(TimeFunction.Create(() => { var remainingCount = SpaceTime.Elements.Where(e => e is FlammableLetter || e is Fire).Count(); if (remainingCount == 0) { Cleanup(); } })); }
public double getMetric(CompressedTrack t1, CompressedTrack t2, int fps) { TimeSpan dt = new TimeSpan(0, 0, 0, 0, (int)Math.Floor(1000.0 / fps)); DateTime startTime1 = t1.startTime; DateTime startTime2 = t2.startTime; DateTime endTime1 = t1.endTime; DateTime endTime2 = t2.endTime; //is there any overlap at all? if (startTime1 > endTime2 || startTime2 > endTime1) { return(0); } //find overlap times DateTime commonStartTime = startTime1; if (startTime2 > startTime1) { commonStartTime = startTime2; } DateTime commonEndTime = endTime1; if (endTime2 < endTime1) { commonEndTime = endTime2; } if (commonEndTime - commonStartTime < dt) { return(0); } //now compute the integral double sum = 0; for (DateTime t = commonStartTime; t <= commonEndTime; t += dt) { SpaceTime l1 = t1.getSpaceTimeAt(t); SpaceTime l2 = t2.getSpaceTimeAt(t); double overlap = BoundingBox.ComputeOverlapAreaFraction(l1.region, l2.region); sum += (overlap * dt.Milliseconds); //pixel-sec } TimeSpan deltat1 = endTime1 - startTime1; TimeSpan deltat2 = endTime2 - startTime2; double max_ms = Math.Max((double)deltat1.TotalMilliseconds, (double)deltat2.TotalMilliseconds); return(sum / max_ms); }
public static List <ICurve> MounthPaths(SpaceTime spaceTime) { List <ICurve> paths = new List <ICurve>(); for (int m = 1; m <= 12; ++m) { spaceTime.Day = 21; spaceTime.Month = m; ICurve path = DailyPath(spaceTime); paths.Add(path); } return(paths); }
private void ListenForEndOfIntro() { SpaceTime.Invoke(async() => { while (SpaceTime.IsRunning) { var remainingCount = SpaceTime.Elements.Where(e => e is FlammableLetter || e is Fire).Count(); if (remainingCount == 0) { Cleanup(); await SpaceTime.YieldAsync(); } } }); }
private void PlaySceneInternal() { // reveal the PowerArgs logo factory.InitializeScene(level).ForEach(e => SpaceTime.Add(e)); // create the character character = new MainCharacter(); // he starts a few pixels from the right edge character.MoveTo(Width - 7, 0); // he moves to the right character.Speed.SpeedX = 5; // he drops a timed mine and turns around when he gets near the right edge ListenForCharacterNearRightEdge(); SpaceTime.Add(character); ListenForEndOfIntro(); }
public static List <ICurve> MounthPaths(Location location) { List <ICurve> paths = new List <ICurve>(); for (int m = 1; m <= 12; ++m) { SpaceTime spaceTime = new SpaceTime { Location = location, Day = 21, Year = 2020, Month = m, }; ICurve path = DailyPath(spaceTime); paths.Add(path); } return(paths); }
public async Task TestSpaceTimeSynchronousException() { var message = "Plain old Exception"; var st = new SpaceTime(80, 40); st.Invoke(() => throw new Exception(message)); bool handled = false; try { await st.Start(); } catch (Exception exc) { var ex = exc.Clean().Single(); Assert.AreEqual(message, ex.Message); handled = true; } Assert.IsTrue(handled); }
public void Cleanup() { if (SpaceTime.IsRunning == false) { return; } SpaceTime.Invoke(async() => { if (introDeferred.Task.IsFulfilled()) { return; } SpaceTime.Elements.ToList().ForEach(e => e.Lifetime.Dispose()); introDeferred.SetResult(true); SpaceTime.Stop(); this.Dispose(); }); }
/***************************************************/ /**** Public Methods ****/ /***************************************************/ public static AnalysisPeriod AnalysisPeriod(SpaceTime spaceTimeStart, SpaceTime spaceTimeEnd) { //DateTime startDateTime = Convert.ToDateTime(spaceTimeStart); //DateTime endDateTime = Convert.ToDateTime(spaceTimeEnd); DateTime startDateTime = new DateTime(spaceTimeStart.Year, spaceTimeStart.Month, spaceTimeStart.Day, spaceTimeStart.Hour, spaceTimeStart.Minute, spaceTimeStart.Second, spaceTimeStart.Millisecond); DateTime endDateTime = new DateTime(spaceTimeEnd.Year, spaceTimeEnd.Month, spaceTimeEnd.Day, spaceTimeEnd.Hour, spaceTimeEnd.Minute, spaceTimeEnd.Second, spaceTimeEnd.Millisecond); PeriodType periodType; TimeSpan period = endDateTime - startDateTime; if (period.TotalHours < 0) { spaceTimeEnd = spaceTimeStart; } if (period.TotalHours >= 1) { if (period.TotalHours > 24) { periodType = PeriodType.Period; } else { periodType = PeriodType.Day; } } else { periodType = PeriodType.Point; } AnalysisPeriod analysisPeriod = new AnalysisPeriod { StartTime = spaceTimeStart, EndTime = spaceTimeEnd, Type = periodType }; return(analysisPeriod); }
public void Cleanup() { if (SpaceTime.IsRunning == false) { return; } SpaceTime.QueueAction(() => { if (introDeferred.IsFulfilled) { return; } SpaceTime.Elements.ToList().ForEach(e => e.Lifetime.Dispose()); SpaceTime.Stop() .Then(introDeferred.Resolve) .Fail((ex => introDeferred.Reject(ex))) .Finally((p) => this.Dispose()); }); }
void Rewind() { if (frame < 0) { if (frame == gameobject.GetComponent <TimeBody>().frame) { gameobject.GetComponent <forces>().stopRewind(); GameObject.Find("speedSlider").GetComponent <time>().updateTimeScale(0f); } else { transform.position = new Vector3(-15, 0, -15); } } else { SpaceTime point = points[frame]; transform.position = point.position; transform.rotation = point.rotation; } }
public void TestTimePerf() { var t = new SpaceTime(80, 30, TimeSpan.FromSeconds(.05)); var now = TimeSpan.Zero; t.Invoke(async() => { for (var i = 0; i < 10000; i++) { t.Add(new DummyFunction()); } while (t.Now < TimeSpan.FromSeconds(100000)) { Assert.AreEqual(now, t.Now); now = now.Add(t.Increment); await t.YieldAsync(); } t.Stop(); }); t.Start().Wait(); }
public void TestCalculateLineOfSightRightToLeft() { var spaceTime = new SpaceTime(100, 100); spaceTime.QueueAction(() => { var from = PowerArgs.Cli.Physics.Rectangular.Create(10, 0, 1, 1); var to = PowerArgs.Cli.Physics.Rectangular.Create(0, 0, 1, 1); var route = from.CalculateLineOfSight(to, 1); Assert.AreEqual(9, route.Steps.Count); Assert.AreEqual(0, route.Obstacles.Count); for (var i = 0; i < route.Steps.Count; i++) { Assert.AreEqual(0, route.Steps[i].Top); // make sure I'm travelling horizontally Assert.AreEqual(9 - i, route.Steps[i].Left); // make sure I moved by 1 towards the target } spaceTime.Stop(); }); spaceTime.Start().Wait(); }
public static DateTime DateTime(this SpaceTime spaceTime) { return(new DateTime(spaceTime.Year, spaceTime.Month, spaceTime.Day, spaceTime.Hour, spaceTime.Minute, spaceTime.Second, spaceTime.Millisecond)); }
public double getMetric(CompressedTrack t1, CompressedTrack t2, int fps) { TimeSpan dt = new TimeSpan(0, 0, 0, 0, (int)Math.Floor(1000.0 / fps)); DateTime startTime1 = t1.startTime; DateTime startTime2 = t2.startTime; DateTime endTime1 = t1.endTime; DateTime endTime2 = t2.endTime; //is there any overlap at all? if (startTime1 > endTime2 || startTime2 > endTime1) { return(0); } //find overlap times DateTime commonStartTime = startTime1; if (startTime2 > startTime1) { commonStartTime = startTime2; } DateTime commonEndTime = endTime1; if (endTime2 < endTime1) { commonEndTime = endTime2; } if (commonEndTime - commonStartTime < dt) { return(0); } //now compute the integral double IntersectionVolume = 0; for (DateTime t = commonStartTime; t <= commonEndTime; t += dt) { SpaceTime l1 = t1.getSpaceTimeAt(t); SpaceTime l2 = t2.getSpaceTimeAt(t); double overlap = BoundingBox.ComputeOverlapArea(l1.region, l2.region); IntersectionVolume += (overlap * dt.Milliseconds); } double UnionVolume = 0; for (DateTime t = startTime1; t <= endTime1; t += dt) { SpaceTime l1 = t1.getSpaceTimeAt(t); UnionVolume += (l1.region.ComputeArea() * dt.Milliseconds); } for (DateTime t = startTime2; t <= endTime2; t += dt) { SpaceTime l2 = t2.getSpaceTimeAt(t); UnionVolume += (l2.region.ComputeArea() * dt.Milliseconds); } UnionVolume -= IntersectionVolume; return(IntersectionVolume / UnionVolume); }
void Record() { points[frame] = new SpaceTime(Arbies.velocity, transform.position, transform.rotation); }
public static DateTime DateTime(this SpaceTime spaceTime) { return(spaceTime.Time.DateTime()); }
public static Sun SolarPosition(this SpaceTime spaceTime) { double latitude = spaceTime.Location.Latitude; double longitude = spaceTime.Location.Longitude; double utcOffset = spaceTime.Location.UtcOffset; DateTime dt = spaceTime.DateTime(); double[][][] R_TERMS = new double[][][] { new double[][] { new double[] { 100013989.0, 0, 0 }, new double[] { 1670700.0, 3.0984635, 6283.07585 }, new double[] { 13956.0, 3.05525, 12566.1517 }, new double[] { 3084.0, 5.1985, 77713.7715 }, new double[] { 1628.0, 1.1739, 5753.3849 }, new double[] { 1576.0, 2.8469, 7860.4194 }, new double[] { 925.0, 5.453, 11506.77 }, new double[] { 542.0, 4.564, 3930.21 }, new double[] { 472.0, 3.661, 5884.927 }, new double[] { 346.0, 0.964, 5507.553 }, new double[] { 329.0, 5.9, 5223.694 }, new double[] { 307.0, 0.299, 5573.143 }, new double[] { 243.0, 4.273, 11790.629 }, new double[] { 212.0, 5.847, 1577.344 }, new double[] { 186.0, 5.022, 10977.079 }, new double[] { 175.0, 3.012, 18849.228 }, new double[] { 110.0, 5.055, 5486.778 }, new double[] { 98, 0.89, 6069.78 }, new double[] { 86, 5.69, 15720.84 }, new double[] { 86, 1.27, 161000.69 }, new double[] { 65, 0.27, 17260.15 }, new double[] { 63, 0.92, 529.69 }, new double[] { 57, 2.01, 83996.85 }, new double[] { 56, 5.24, 71430.7 }, new double[] { 49, 3.25, 2544.31 }, new double[] { 47, 2.58, 775.52 }, new double[] { 45, 5.54, 9437.76 }, new double[] { 43, 6.01, 6275.96 }, new double[] { 39, 5.36, 4694 }, new double[] { 38, 2.39, 8827.39 }, new double[] { 37, 0.83, 19651.05 }, new double[] { 37, 4.9, 12139.55 }, new double[] { 36, 1.67, 12036.46 }, new double[] { 35, 1.84, 2942.46 }, new double[] { 33, 0.24, 7084.9 }, new double[] { 32, 0.18, 5088.63 }, new double[] { 32, 1.78, 398.15 }, new double[] { 28, 1.21, 6286.6 }, new double[] { 28, 1.9, 6279.55 }, new double[] { 26, 4.59, 10447.39 } }, new double[][] { new double[] { 103019.0, 1.10749, 6283.07585 }, new double[] { 1721.0, 1.0644, 12566.1517 }, new double[] { 702.0, 3.142, 0 }, new double[] { 32, 1.02, 18849.23 }, new double[] { 31, 2.84, 5507.55 }, new double[] { 25, 1.32, 5223.69 }, new double[] { 18, 1.42, 1577.34 }, new double[] { 10, 5.91, 10977.08 }, new double[] { 9, 1.42, 6275.96 }, new double[] { 9, 0.27, 5486.78 } }, new double[][] { new double[] { 4359.0, 5.7846, 6283.0758 }, new double[] { 124.0, 5.579, 12566.152 }, new double[] { 12, 3.14, 0 }, new double[] { 9, 3.63, 77713.77 }, new double[] { 6, 1.87, 5573.14 }, new double[] { 3, 5.47, 18849.23 } }, new double[][] { new double[] { 145.0, 4.273, 6283.076 }, new double[] { 7, 3.92, 12566.15 } }, new double[][] { new double[] { 4, 2.56, 6283.08 } } }; int[] r_subcount = { 40, 10, 6, 2, 1 }; int[][] Y_TERMS = new int[][] { new int[] { 0, 0, 0, 0, 1 }, new int[] { -2, 0, 0, 2, 2 }, new int[] { 0, 0, 0, 2, 2 }, new int[] { 0, 0, 0, 0, 2 }, new int[] { 0, 1, 0, 0, 0 }, new int[] { 0, 0, 1, 0, 0 }, new int[] { -2, 1, 0, 2, 2 }, new int[] { 0, 0, 0, 2, 1 }, new int[] { 0, 0, 1, 2, 2 }, new int[] { -2, -1, 0, 2, 2 }, new int[] { -2, 0, 1, 0, 0 }, new int[] { -2, 0, 0, 2, 1 }, new int[] { 0, 0, -1, 2, 2 }, new int[] { 2, 0, 0, 0, 0 }, new int[] { 0, 0, 1, 0, 1 }, new int[] { 2, 0, -1, 2, 2 }, new int[] { 0, 0, -1, 0, 1 }, new int[] { 0, 0, 1, 2, 1 }, new int[] { -2, 0, 2, 0, 0 }, new int[] { 0, 0, -2, 2, 1 }, new int[] { 2, 0, 0, 2, 2 }, new int[] { 0, 0, 2, 2, 2 }, new int[] { 0, 0, 2, 0, 0 }, new int[] { -2, 0, 1, 2, 2 }, new int[] { 0, 0, 0, 2, 0 }, new int[] { -2, 0, 0, 2, 0 }, new int[] { 0, 0, -1, 2, 1 }, new int[] { 0, 2, 0, 0, 0 }, new int[] { 2, 0, -1, 0, 1 }, new int[] { -2, 2, 0, 2, 2 }, new int[] { 0, 1, 0, 0, 1 }, new int[] { -2, 0, 1, 0, 1 }, new int[] { 0, -1, 0, 0, 1 }, new int[] { 0, 0, 2, -2, 0 }, new int[] { 2, 0, -1, 2, 1 }, new int[] { 2, 0, 1, 2, 2 }, new int[] { 0, 1, 0, 2, 2 }, new int[] { -2, 1, 1, 0, 0 }, new int[] { 0, -1, 0, 2, 2 }, new int[] { 2, 0, 0, 2, 1 }, new int[] { 2, 0, 1, 0, 0 }, new int[] { -2, 0, 2, 2, 2 }, new int[] { -2, 0, 1, 2, 1 }, new int[] { 2, 0, -2, 0, 1 }, new int[] { 2, 0, 0, 0, 1 }, new int[] { 0, -1, 1, 0, 0 }, new int[] { -2, -1, 0, 2, 1 }, new int[] { -2, 0, 0, 0, 1 }, new int[] { 0, 0, 2, 2, 1 }, new int[] { -2, 0, 2, 0, 1 }, new int[] { -2, 1, 0, 2, 1 }, new int[] { 0, 0, 1, -2, 0 }, new int[] { -1, 0, 1, 0, 0 }, new int[] { -2, 1, 0, 0, 0 }, new int[] { 1, 0, 0, 0, 0 }, new int[] { 0, 0, 1, 2, 0 }, new int[] { 0, 0, -2, 2, 2 }, new int[] { -1, -1, 1, 0, 0 }, new int[] { 0, 1, 1, 0, 0 }, new int[] { 0, -1, 1, 2, 2 }, new int[] { 2, -1, -1, 2, 2 }, new int[] { 0, 0, 3, 2, 2 }, new int[] { 2, -1, 0, 2, 2 }, }; double[][] PE_TERMS = new double[][] { new double[] { -171996, -174.2, 92025, 8.9 }, new double[] { -13187, -1.6, 5736, -3.1 }, new double[] { -2274, -0.2, 977, -0.5 }, new double[] { 2062, 0.2, -895, 0.5 }, new double[] { 1426, -3.4, 54, -0.1 }, new double[] { 712, 0.1, -7, 0 }, new double[] { -517, 1.2, 224, -0.6 }, new double[] { -386, -0.4, 200, 0 }, new double[] { -301, 0, 129, -0.1 }, new double[] { 217, -0.5, -95, 0.3 }, new double[] { -158, 0, 0, 0 }, new double[] { 129, 0.1, -70, 0 }, new double[] { 123, 0, -53, 0 }, new double[] { 63, 0, 0, 0 }, new double[] { 63, 0.1, -33, 0 }, new double[] { -59, 0, 26, 0 }, new double[] { -58, -0.1, 32, 0 }, new double[] { -51, 0, 27, 0 }, new double[] { 48, 0, 0, 0 }, new double[] { 46, 0, -24, 0 }, new double[] { -38, 0, 16, 0 }, new double[] { -31, 0, 13, 0 }, new double[] { 29, 0, 0, 0 }, new double[] { 29, 0, -12, 0 }, new double[] { 26, 0, 0, 0 }, new double[] { -22, 0, 0, 0 }, new double[] { 21, 0, -10, 0 }, new double[] { 17, -0.1, 0, 0 }, new double[] { 16, 0, -8, 0 }, new double[] { -16, 0.1, 7, 0 }, new double[] { -15, 0, 9, 0 }, new double[] { -13, 0, 7, 0 }, new double[] { -12, 0, 6, 0 }, new double[] { 11, 0, 0, 0 }, new double[] { -10, 0, 5, 0 }, new double[] { -8, 0, 3, 0 }, new double[] { 7, 0, -3, 0 }, new double[] { -7, 0, 0, 0 }, new double[] { -7, 0, 3, 0 }, new double[] { -7, 0, 3, 0 }, new double[] { 6, 0, 0, 0 }, new double[] { 6, 0, -3, 0 }, new double[] { 6, 0, -3, 0 }, new double[] { -6, 0, 3, 0 }, new double[] { -6, 0, 3, 0 }, new double[] { 5, 0, 0, 0 }, new double[] { -5, 0, 3, 0 }, new double[] { -5, 0, 3, 0 }, new double[] { -5, 0, 3, 0 }, new double[] { 4, 0, 0, 0 }, new double[] { 4, 0, 0, 0 }, new double[] { 4, 0, 0, 0 }, new double[] { -4, 0, 0, 0 }, new double[] { -4, 0, 0, 0 }, new double[] { -4, 0, 0, 0 }, new double[] { 3, 0, 0, 0 }, new double[] { -3, 0, 0, 0 }, new double[] { -3, 0, 0, 0 }, new double[] { -3, 0, 0, 0 }, new double[] { -3, 0, 0, 0 }, new double[] { -3, 0, 0, 0 }, new double[] { -3, 0, 0, 0 }, new double[] { -3, 0, 0, 0 }, }; double[][][] L_TERMS = new double[][][] { new double[][] { new double[] { 175347046.0, 0, 0 }, new double[] { 3341656.0, 4.6692568, 6283.07585 }, new double[] { 34894.0, 4.6261, 12566.1517 }, new double[] { 3497.0, 2.7441, 5753.3849 }, new double[] { 3418.0, 2.8289, 3.5231 }, new double[] { 3136.0, 3.6277, 77713.7715 }, new double[] { 2676.0, 4.4181, 7860.4194 }, new double[] { 2343.0, 6.1352, 3930.2097 }, new double[] { 1324.0, 0.7425, 11506.7698 }, new double[] { 1273.0, 2.0371, 529.691 }, new double[] { 1199.0, 1.1096, 1577.3435 }, new double[] { 990, 5.233, 5884.927 }, new double[] { 902, 2.045, 26.298 }, new double[] { 857, 3.508, 398.149 }, new double[] { 780, 1.179, 5223.694 }, new double[] { 753, 2.533, 5507.553 }, new double[] { 505, 4.583, 18849.228 }, new double[] { 492, 4.205, 775.523 }, new double[] { 357, 2.92, 0.067 }, new double[] { 317, 5.849, 11790.629 }, new double[] { 284, 1.899, 796.298 }, new double[] { 271, 0.315, 10977.079 }, new double[] { 243, 0.345, 5486.778 }, new double[] { 206, 4.806, 2544.314 }, new double[] { 205, 1.869, 5573.143 }, new double[] { 202, 2.458, 6069.777 }, new double[] { 156, 0.833, 213.299 }, new double[] { 132, 3.411, 2942.463 }, new double[] { 126, 1.083, 20.775 }, new double[] { 115, 0.645, 0.98 }, new double[] { 103, 0.636, 4694.003 }, new double[] { 102, 0.976, 15720.839 }, new double[] { 102, 4.267, 7.114 }, new double[] { 99, 6.21, 2146.17 }, new double[] { 98, 0.68, 155.42 }, new double[] { 86, 5.98, 161000.69 }, new double[] { 85, 1.3, 6275.96 }, new double[] { 85, 3.67, 71430.7 }, new double[] { 80, 1.81, 17260.15 }, new double[] { 79, 3.04, 12036.46 }, new double[] { 75, 1.76, 5088.63 }, new double[] { 74, 3.5, 3154.69 }, new double[] { 74, 4.68, 801.82 }, new double[] { 70, 0.83, 9437.76 }, new double[] { 62, 3.98, 8827.39 }, new double[] { 61, 1.82, 7084.9 }, new double[] { 57, 2.78, 6286.6 }, new double[] { 56, 4.39, 14143.5 }, new double[] { 56, 3.47, 6279.55 }, new double[] { 52, 0.19, 12139.55 }, new double[] { 52, 1.33, 1748.02 }, new double[] { 51, 0.28, 5856.48 }, new double[] { 49, 0.49, 1194.45 }, new double[] { 41, 5.37, 8429.24 }, new double[] { 41, 2.4, 19651.05 }, new double[] { 39, 6.17, 10447.39 }, new double[] { 37, 6.04, 10213.29 }, new double[] { 37, 2.57, 1059.38 }, new double[] { 36, 1.71, 2352.87 }, new double[] { 36, 1.78, 6812.77 }, new double[] { 33, 0.59, 17789.85 }, new double[] { 30, 0.44, 83996.85 }, new double[] { 30, 2.74, 1349.87 }, new double[] { 25, 3.16, 4690.48 } }, new double[][] { new double[] { 628331966747.0, 0, 0 }, new double[] { 206059.0, 2.678235, 6283.07585 }, new double[] { 4303.0, 2.6351, 12566.1517 }, new double[] { 425.0, 1.59, 3.523 }, new double[] { 119.0, 5.796, 26.298 }, new double[] { 109.0, 2.966, 1577.344 }, new double[] { 93, 2.59, 18849.23 }, new double[] { 72, 1.14, 529.69 }, new double[] { 68, 1.87, 398.15 }, new double[] { 67, 4.41, 5507.55 }, new double[] { 59, 2.89, 5223.69 }, new double[] { 56, 2.17, 155.42 }, new double[] { 45, 0.4, 796.3 }, new double[] { 36, 0.47, 775.52 }, new double[] { 29, 2.65, 7.11 }, new double[] { 21, 5.34, 0.98 }, new double[] { 19, 1.85, 5486.78 }, new double[] { 19, 4.97, 213.3 }, new double[] { 17, 2.99, 6275.96 }, new double[] { 16, 0.03, 2544.31 }, new double[] { 16, 1.43, 2146.17 }, new double[] { 15, 1.21, 10977.08 }, new double[] { 12, 2.83, 1748.02 }, new double[] { 12, 3.26, 5088.63 }, new double[] { 12, 5.27, 1194.45 }, new double[] { 12, 2.08, 4694 }, new double[] { 11, 0.77, 553.57 }, new double[] { 10, 1.3, 6286.6 }, new double[] { 10, 4.24, 1349.87 }, new double[] { 9, 2.7, 242.73 }, new double[] { 9, 5.64, 951.72 }, new double[] { 8, 5.3, 2352.87 }, new double[] { 6, 2.65, 9437.76 }, new double[] { 6, 4.67, 4690.48 } }, new double[][] { new double[] { 52919.0, 0, 0 }, new double[] { 8720.0, 1.0721, 6283.0758 }, new double[] { 309.0, 0.867, 12566.152 }, new double[] { 27, 0.05, 3.52 }, new double[] { 16, 5.19, 26.3 }, new double[] { 16, 3.68, 155.42 }, new double[] { 10, 0.76, 18849.23 }, new double[] { 9, 2.06, 77713.77 }, new double[] { 7, 0.83, 775.52 }, new double[] { 5, 4.66, 1577.34 }, new double[] { 4, 1.03, 7.11 }, new double[] { 4, 3.44, 5573.14 }, new double[] { 3, 5.14, 796.3 }, new double[] { 3, 6.05, 5507.55 }, new double[] { 3, 1.19, 242.73 }, new double[] { 3, 6.12, 529.69 }, new double[] { 3, 0.31, 398.15 }, new double[] { 3, 2.28, 553.57 }, new double[] { 2, 4.38, 5223.69 }, new double[] { 2, 3.75, 0.98 } }, new double[][] { new double[] { 289.0, 5.844, 6283.076 }, new double[] { 35, 0, 0 }, new double[] { 17, 5.49, 12566.15 }, new double[] { 3, 5.2, 155.42 }, new double[] { 1, 4.72, 3.52 }, new double[] { 1, 5.3, 18849.23 }, new double[] { 1, 5.97, 242.73 } }, new double[][] { new double[] { 114.0, 3.142, 0 }, new double[] { 8, 4.13, 6283.08 }, new double[] { 1, 3.84, 12566.15 } }, new double[][] { new double[] { 1, 3.14, 0 } } }; int[] l_subcount = { 64, 34, 20, 7, 3, 1 }; double[][][] B_TERMS = new double[][][] { new double[][] { new double[] { 280.0, 3.199, 84334.662 }, new double[] { 102.0, 5.422, 5507.553 }, new double[] { 80, 3.88, 5223.69 }, new double[] { 44, 3.7, 2352.87 }, new double[] { 32, 4, 1577.34 } }, new double[][] { new double[] { 9, 3.9, 5507.55 }, new double[] { 6, 1.73, 5223.69 } } }; int[] b_subcount = { 5, 2 }; double PI = 3.1415926535897932384626433832795028841971; double julianDay = JulianDay(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, utcOffset); double julianCentury = (julianDay - 2451545.0) / 36525.0; double julianEphemerisDay = julianDay; // / 86400.0; double julianEphemerisCentury = (julianEphemerisDay - 2451545.0) / 36525.0; double julianEphemerisMillenium = (julianEphemerisCentury / 10.0); //EarthRadiusVector double[] sum = new double[5]; for (int x2 = 0; x2 < 5; x2++) { double s = 0; for (int y2 = 0; y2 < r_subcount[x2]; y2++) { s += R_TERMS[x2][y2][0] * Math.Cos(R_TERMS[x2][y2][1] + R_TERMS[x2][y2][2] * julianEphemerisMillenium); } sum[x2] = s; } //Earth Values double R = 0; for (int x3 = 0; x3 < 5; x3++) { R += sum[x3] * Math.Pow(julianEphemerisMillenium, x3); } R /= 1.0e8; double[] meanTerms = new double[5]; meanTerms[0] = ThirdOrderPolynomial(1.0 / 189474.0, -0.0019142, 445267.11148, 297.85036, julianEphemerisCentury); //MeanElongationMoonSun meanTerms[1] = ThirdOrderPolynomial(-1.0 / 300000.0, -0.0001603, 35999.05034, 357.52772, julianEphemerisCentury); //MeanAnomalySun meanTerms[2] = ThirdOrderPolynomial(1.0 / 56250.0, 0.0086972, 477198.867398, 134.96298, julianEphemerisCentury); //MeanAnomalyMoon meanTerms[3] = ThirdOrderPolynomial(1.0 / 327270.0, -0.0036825, 483202.017538, 93.27191, julianEphemerisCentury); //ArgumentLatitudeMoon meanTerms[4] = ThirdOrderPolynomial(1.0 / 450000.0, 0.0020708, -1934.136261, 125.04452, julianEphemerisCentury); //AscendingLongitudeMoon //Nutation Longitude and Obliquity double delPsi = 0; double delEpsilon = 0; for (int x4 = 0; x4 < 63; x4++) { double xyTermSummation = 0; for (int y3 = 0; y3 < meanTerms.Length; y3++) { xyTermSummation += meanTerms[y3] * Y_TERMS[x4][y3]; } xyTermSummation = Convert.ToRadians(xyTermSummation, PI); delPsi += (PE_TERMS[x4][0] + julianEphemerisCentury * PE_TERMS[x4][1]) * Math.Sin(xyTermSummation); delEpsilon += (PE_TERMS[x4][2] + julianEphemerisCentury * PE_TERMS[x4][3]) * Math.Cos(xyTermSummation); } delPsi /= 36000000.0; delEpsilon /= 36000000.0; double u = julianEphemerisMillenium / 10; double epsilon0 = 84381.448 + u * (-4680.93 + u * (-1.55 + u * (1999.25 + u * (-51.38 + u * (-249.67 + u * (-39.05 + u * (7.12 + u * (27.87 + u * (5.79 + u * 2.45))))))))); //EclipticMeanObliquity double epsilon = delEpsilon + epsilon0 / 3600.0; //EclipticTrueObliquity //Greenwich Mean Sidereal Time double nu0 = 280.46061837 + 360.98564736629 * (julianDay - 2451545.0) + julianCentury * julianCentury * (0.000387933 - julianCentury / 38710000.0); nu0 /= 360; double limit = 360 * (nu0 - Math.Floor(nu0)); if (limit < 0) { limit += 360; } nu0 = limit; double nu = nu0 + delPsi * Math.Cos(Convert.ToRadians(epsilon, PI)); //Greenwich Sidereal Time //EarthHeliocentricLongitude double l = 0; double[] sum2 = new double[6]; for (int x5 = 0; x5 < sum2.Length; x5++) { for (int y5 = 0; y5 < l_subcount[x5]; y5++) { sum2[x5] += L_TERMS[x5][y5][0] * Math.Cos(L_TERMS[x5][y5][1] + L_TERMS[x5][y5][2] * julianEphemerisMillenium); } } for (int x6 = 0; x6 < sum2.Length; x6++) { l += sum2[x6] * Math.Pow(julianEphemerisMillenium, x6); } l /= 1.0e8; l = Convert.ToDegrees(l, PI); l /= 360; limit = 360 * (l - Math.Floor(l)); if (limit < 0) { limit += 360; } l = limit; //EarthHeliocentricLatitude double b = 0; sum2 = new double[2]; for (int x7 = 0; x7 < sum2.Length; x7++) { for (int y7 = 0; y7 < b_subcount[x7]; y7++) { sum2[x7] += B_TERMS[x7][y7][0] * Math.Cos(B_TERMS[x7][y7][1] + B_TERMS[x7][y7][2] * julianEphemerisMillenium); } } for (int x8 = 0; x8 < sum2.Length; x8++) { b += sum2[x8] * Math.Pow(julianEphemerisMillenium, x8); } b /= 1.0e8; b = Convert.ToDegrees(b, PI); //GeocentricLongitude double theta = l + 180; if (theta >= 360) { theta -= 360; } //GeocentricLatitude double beta = -b; double delTau = -20.4898 / (3600.0 * R); //AberrationCorrection double lamba = theta + delPsi + delTau; //ApparentSunLongitude //GeocentricRightAscension double alpha = Convert.ToDegrees(Math.Atan2(Math.Sin(Convert.ToRadians(lamba, PI)) * Math.Cos(Convert.ToRadians(epsilon, PI) - Math.Tan(Convert.ToRadians(beta, PI)) * Math.Sin(Convert.ToRadians(epsilon, PI))), Math.Cos(Convert.ToRadians(lamba, PI))), PI); alpha /= 360; limit = 360 * (alpha - Math.Floor(alpha)); if (limit < 0) { limit += 360; } alpha = limit; double delta = Convert.ToDegrees(Math.Asin(Math.Sin(Convert.ToRadians(beta, PI)) * Math.Cos(Convert.ToRadians(epsilon, PI)) + Math.Cos(Convert.ToRadians(beta, PI)) * Math.Sin(Convert.ToRadians(epsilon, PI) * Math.Sin(Convert.ToRadians(lamba, PI)))), PI); //GeocentricDeclination //Observe Hour Angle double H = nu + longitude - alpha; H /= 360; limit = 360 * (H - Math.Floor(H)); if (limit < 0) { limit += 360; } H = limit; double xi = 8.794 / (3600.0 * R); //SunEquatorialHorizontalParallax //RightAscensionParallaxAndTopocentricDec double latRad = Convert.ToRadians(latitude, PI); double xiRad = Convert.ToRadians(xi, PI); double hRad = Convert.ToRadians(H, PI); double deltaRad = Convert.ToRadians(delta, PI); double u2 = Math.Atan(0.99664719 * Math.Tan(latRad)); double y = 0.99664719 * Math.Sin(u2) * Math.Sin(latRad) / 6378140.0; double x = Math.Cos(u2) * Math.Cos(latRad) / 6378140.0; var deltaAlphaRad = Math.Atan2(-x * Math.Sin(xiRad) * Math.Sin(hRad), Math.Cos(deltaRad) - x * Math.Sin(xiRad) * Math.Cos(hRad)); double deltaPrime = Convert.ToDegrees(Math.Atan2((Math.Sin(deltaRad) - y * Math.Sin(xiRad)) * Math.Cos(deltaAlphaRad), Math.Cos(deltaRad) - x * Math.Sin(xiRad) * Math.Cos(hRad)), PI); double deltaAlpha = Convert.ToDegrees(deltaAlphaRad, PI); double hPrime = H - deltaAlpha; //TopocentricLocalHourAngle //TopocentricAzimuthAngleAstro double azimuthAstro = Convert.ToDegrees(Math.Atan2(Math.Sin(Convert.ToRadians(hPrime, PI)), Math.Cos(Convert.ToRadians(hPrime, PI)) * Math.Sin(Convert.ToRadians(latitude, PI)) - Math.Tan(Convert.ToRadians(deltaPrime, PI)) * Math.Cos(Convert.ToRadians(latitude, PI))), PI); azimuthAstro /= 360; limit = 360 * (azimuthAstro - Math.Floor(azimuthAstro)); if (limit < 0) { limit += 360; } azimuthAstro = limit; //TopocentricAzimuthAngle double azimuth = azimuthAstro + 180; azimuth /= 360; limit = 360 * (azimuth - Math.Floor(azimuth)); if (limit < 0) { limit += 360; } azimuth = limit; double e0 = Convert.ToDegrees(Math.Asin(Math.Sin(latRad) * Math.Sin(Convert.ToRadians(deltaPrime, PI)) + Math.Cos(latRad) * Math.Cos(Convert.ToRadians(deltaPrime, PI)) * Math.Cos(Convert.ToRadians(hPrime, PI))), PI); //TopocentricElevationAngle double zenith = 90.0 - e0; return(new Sun { Altitude = (90 - zenith), Azimuth = azimuth }); }