public void Test1()
        {
            To   = TerrainPatch.FromId(new Point(103, 138));
            From = TerrainPatch.FromId(new Point(103, 139));

            To.FillPointsAndMatrices(Terrain);
            From.FillPoints(Terrain);
            To.UpdateHorizonBugHunt(From);
            Console.WriteLine(@"Test1 finished.");
        }
        private CurveItem GetSunCurve(TerrainPatch patch, Point pt, math.Vector3d sun, Color color)
        {
            patch.FillPointsAndMatrices(LunarHorizon.Terrain);
            patch.GetAzEl(sun, pt.X, pt.Y, out float az_rad, out float el_rad);

            {
                var horizon = patch.GetHorizon(pt.Y, pt.X);
                var frac    = (byte)(255f * horizon.SunFraction2(az_rad * 180f / 3.141592653589f, el_rad * 180f / 3.141592653589f));
                Console.WriteLine($"patch.id={patch.Id} pt=[{pt.X},{pt.Y}] Sun frac={frac}");
            }

            var          az_deg = az_rad * 180f / 3.141592565589f;
            var          el_deg = el_rad * 180f / 3.141592565589f;
            const int    count  = 12;
            const double radius = 32d / 60d;
            var          points = new PointPairList();

            for (var i = 0; i <= count; i++)
            {
                var ang = i * 2d * Math.PI / count;
                points.Add(az_deg + radius * Math.Cos(ang), el_deg + radius * Math.Sin(ang));
            }
            return(new LineItem(null, points, color, SymbolType.None));
        }
Beispiel #3
0
        protected override void OnPaint(PaintEventArgs e)
        {
            if (!ReadyToRender())
            {
                return;
            }
            if (_bitmap == null || _bitmap.Width != Width || _bitmap.Height != Height)
            {
                _bitmap?.Dispose();
                _bitmap = new Bitmap(Width, Height, PixelFormat.Format32bppArgb);
            }

            Patch.FillPointsAndMatrices(Terrain);
            var m    = Patch.Matrices[PointInPatch.Y][PointInPatch.X];
            var temp = new Vector3d();

            TerrainPatch.Transform(ref ShadowCaster, ref m, ref temp);

            var x           = temp[0];
            var y           = temp[1];
            var z           = temp[2];
            var azimuth_rad = Math.Atan2(y, x) + Math.PI;  // [0,2PI]
            var alen        = Math.Sqrt(x * x + y * y);
            var slope       = z / alen;

            var elevation_deg = ((float)Math.Atan(slope)) * 180f / 3.141592653589f;

            var normalized_azimuth = azimuth_rad / (2d * Math.PI);  // range [0,1)
            var horizon_index_f    = (float)(Horizon.HorizonSamplesD * normalized_azimuth);

            var buf = Patch.Horizons[PointInPatch.Y][PointInPatch.X].Buffer;

            var width  = _bitmap.Width;
            var height = _bitmap.Height;

            var sunCenter = new Point(width / 2, height / 2);
            var sunRadius = 8; //  was 20

            // The width of a single slat in pixels
            const float sun_width_deg = .25f;
            var         slat_width    = sunRadius; // .25 deg
            var         slat_width2   = slat_width / 2;

            // The index of the slat that 'covers' the sun's center
            var index_center     = (int)horizon_index_f;
            var center_slat_left = (int)((sunCenter.X - (horizon_index_f - index_center) * sunRadius) + 0.5f);

            //Console.WriteLine($"caster render idx={index_center} horizon_elev={LookupHorizon(buf, index_center)} sun_elev={elevation_deg}");

            var span  = (width / 2) / sunRadius + 1;
            var span2 = 2 * span;

            using (var g = Graphics.FromImage(_bitmap))
            {
                g.FillRectangle(Brushes.White, 0, 0, _bitmap.Width, _bitmap.Height);
                g.FillEllipse(Brushes.Yellow, sunCenter.X - sunRadius, sunCenter.Y - sunRadius, sunRadius * 2, sunRadius * 2);

                for (var slat_offset = -span; slat_offset <= span2; slat_offset++)
                {
                    var slat_left   = center_slat_left + slat_offset * slat_width;
                    var slat_index  = index_center + slat_offset;
                    var slat_angle1 = LookupHorizon(buf, slat_index);
                    var slat_angle2 = LookupHorizon(buf, slat_index - 1);
                    var slat_top1   = sunCenter.Y + ((elevation_deg - slat_angle1) / sun_width_deg) * sunRadius;
                    var slat_top2   = sunCenter.Y + ((elevation_deg - slat_angle2) / sun_width_deg) * sunRadius;

                    //Console.WriteLine($"  slat_top={slat_top1} slat_angle={slat_angle1}");
                    var top = Math.Max(0, slat_top1);

                    g.FillRectangle(_grayBrush, slat_left, top, slat_width, height);
                    g.DrawRectangle(Pens.DarkGray, slat_left, top, slat_width, height);

                    g.DrawLine(Pens.Red, slat_left - slat_width2, slat_top2, slat_left + slat_width2, slat_top1);
                }

                var azimuth_deg = azimuth_rad * 180d / Math.PI;
                var frac        = SunFraction2(g, sunCenter, sunRadius, buf, (float)azimuth_deg, elevation_deg);
                Console.WriteLine($"sun frac={frac}");
            }
            e.Graphics.DrawImage(_bitmap, 0, 0);
        }