private bool DoCalculation(ConsolidatedLine c)
        {
            var normal = GetSurfaceNormal(c.Pixel.Y, c.Pixel.X);

            c.NormalX = normal.X;
            c.NormalY = normal.Y;
            c.NormalZ = normal.Z;
            var steps  = (_stop.Ticks - _start.Ticks) / _step.Ticks;
            var result = new List <float>((int)steps + 10);

            if (true)
            {
                if (!MapOverSunContribution(c.Pixel.Y, c.Pixel.X, _start, _stop, _step, (time, sun_contrib) => result.Add(sun_contrib)))
                {
                    return(false);
                }
            }
            else
            {
                if (!MapOverLightCurve(c.Pixel.Y, c.Pixel.X, _start, _stop, _step, (time, light) => result.Add(light)))
                {
                    return(false);
                }
            }
            c.Lighting = result.ToArray();
            return(true);
        }
 internal void WriteIceDepthCorrelation()
 {
     using (var tw = new StreamWriter(IceStabilityDepthCorrelationFilename))
         using (var fs = File.OpenRead(LightingCacheFilename))
             using (var br = new BinaryReader(fs))
             {
                 tw.WriteLine("x,y,siegler_depth,max_temp");
                 try
                 {
                     while (true)
                     {
                         var l = ConsolidatedLine.ReadFrom(br);
                         tw.WriteLine($"{l.Pixel.X},{l.Pixel.Y},{l.Depth},{l.Lighting.BoxFilter(3).Max()},{l.Lighting.BoxFilter(6).Max()},{l.Lighting.BoxFilter(9).Max()},{l.Lighting.BoxFilter(12).Max()}");
                     }
                 } catch (Exception) { }
             }
 }
        // Cache by id
        private bool HorizonsHaveBeenCalculated(ConsolidatedLine consolidated)
        {
            var pixel = consolidated.Pixel;
            var id    = TerrainPatch.LineSampleToId(pixel.Y, pixel.X);

            lock (_precache)
            {
                if (_precache.TryGetValue(id, out bool hasHorizons))
                {
                    return(hasHorizons);
                }
                var patch         = TerrainPatch.FromId(id);
                var horizons_path = patch.Path;
                var result        = File.Exists(horizons_path);
                if (result)
                {
                    _cache.Add(id, patch);
                }
                _precache.Add(id, result);
                return(result);
            }
        }