public void MapOverLightCurve(int line, int sample, DateTime start, DateTime stop, TimeSpan step, Action <DateTime, float> action) { var id = TerrainPatch.LineSampleToId(line, sample); var patch = GetPatch(id); if (patch == null) { return; } var y_offset = line - patch.Line; var x_offset = sample - patch.Sample; var mat = patch.Matrices[y_offset][x_offset]; var horizon = patch.Horizons[y_offset][x_offset]; if (!horizon.IsDegrees) { lock (horizon) horizon.ConvertSlopeToDegrees(); } var cache = SunVectorCache.GetSingleton(); var temp = new Vector3d(); for (var time = start; time <= stop; time += step) { var sunvec = cache.SunPosition(time); TerrainPatch.Transform(ref sunvec, ref mat, ref temp); var sun_x = temp[0]; var sun_y = temp[1]; var sun_z = temp[2]; var azimuth_rad = Math.Atan2(sun_y, sun_x) + Math.PI; // [0,2PI] var azimuth_deg = (float)(azimuth_rad * 180d / Math.PI); var alen = Math.Sqrt(sun_x * sun_x + sun_y * sun_y); var slope = sun_z / alen; var elevation_deg = ((float)Math.Atan(slope)) * 180f / 3.141592653589f; var sun = horizon.SunFraction2(azimuth_deg, elevation_deg); //Console.WriteLine($"time={time} elevation_deg={elevation_deg} sun={sun}"); action(time, sun); } }
public static SunVectorCache GetSingleton() => _singleton != null ? _singleton : _singleton = new SunVectorCache();