コード例 #1
0
ファイル: MeasureToolRenderer.cs プロジェクト: t9mike/ADK
        /// <summary>
        /// Does the rendering logic
        /// </summary>
        /// <param name="map">Map instance</param>
        public override void Render(IMapContext map)
        {
            if (IsMeasureToolOn && map.MousePosition != null)
            {
                double coeff = map.DiagonalCoefficient();

                List <PointF> points = new List <PointF>();
                for (int f = 0; f <= 10; f++)
                {
                    CrdsHorizontal h = Angle.Intermediate(map.MousePosition, MeasureOrigin, f / 10.0);
                    points.Add(map.Project(h));
                    if (Angle.Separation(h, map.Center) > map.ViewAngle * coeff)
                    {
                        break;
                    }
                }

                if (points.Count > 1)
                {
                    map.Graphics.DrawCurve(new Pen(map.GetColor(Color.White)), points.ToArray());
                    double angle = Angle.Separation(map.MousePosition, MeasureOrigin);
                    PointF p     = map.Project(map.MousePosition);
                    map.Graphics.DrawString(Formatters.MeasuredAngle.Format(angle), fontAngleValue, new SolidBrush(map.GetColor(Color.White)), p.X + 5, p.Y + 5);
                }
            }
        }
コード例 #2
0
ファイル: ConstellationsRenderer.cs プロジェクト: t9mike/ADK
        /// <summary>
        /// Renders constellation borders on the map
        /// </summary>
        private void RenderBorders(IMapContext map)
        {
            PointF         p1, p2;
            CrdsHorizontal h1, h2;
            var            borders   = constellationsCalc.ConstBorders;
            bool           isGround  = settings.Get <bool>("Ground");
            double         coeff     = map.DiagonalCoefficient();
            Pen            penBorder = new Pen(map.GetColor("ColorConstBorders"));

            foreach (var block in borders)
            {
                for (int i = 0; i < block.Count - 1; i++)
                {
                    h1 = block.ElementAt(i).Horizontal;
                    h2 = block.ElementAt(i + 1).Horizontal;

                    if ((!isGround || h1.Altitude >= 0 || h2.Altitude >= 0) &&
                        Angle.Separation(map.Center, h1) < 90 * coeff &&
                        Angle.Separation(map.Center, h2) < 90 * coeff)
                    {
                        p1 = map.Project(h1);
                        p2 = map.Project(h2);

                        var points = map.SegmentScreenIntersection(p1, p2);
                        if (points.Length == 2)
                        {
                            map.Graphics.DrawLine(penBorder, points[0], points[1]);
                        }
                    }
                }
            }
        }
コード例 #3
0
ファイル: NovaeRenderer.cs プロジェクト: Astrarium/Astrarium
        public override void Render(IMapContext map)
        {
            Graphics g         = map.Graphics;
            bool     isGround  = settings.Get <bool>("Ground");
            bool     showNovae = settings.Get("Stars") && settings.Get <bool>("Novae");

            if (!showNovae)
            {
                return;
            }

            var novae = calc.Novae.Where(m => Angle.Separation(map.Center, m.Horizontal) < map.ViewAngle);

            if (isGround)
            {
                novae = novae.Where(m => m.Horizontal.Altitude >= 0);
            }

            var font  = SystemFonts.DefaultFont;
            var brush = new SolidBrush(map.Schema == ColorSchema.White ? Color.Black : Color.White);

            foreach (var star in novae)
            {
                float diam = map.GetPointSize(star.Mag);
                if ((int)diam > 0)
                {
                    PointF p = map.Project(star.Horizontal);
                    if (!map.IsOutOfScreen(p))
                    {
                        if (map.Schema == ColorSchema.White)
                        {
                            g.FillEllipse(Brushes.White, p.X - diam / 2 - 1, p.Y - diam / 2 - 1, diam + 2, diam + 2);
                        }

                        g.FillEllipse(brush, p.X - diam / 2, p.Y - diam / 2, diam, diam);

                        map.AddDrawnObject(star);
                    }
                }
            }

            if (settings.Get <bool>("StarsLabels") && settings.Get <bool>("NovaeLabels") && map.ViewAngle <= limitAllNames)
            {
                brushStarNames = new SolidBrush(map.GetColor("ColorStarsLabels"));

                foreach (var nova in novae)
                {
                    float diam = map.GetPointSize(nova.Mag);
                    if ((int)diam > 0)
                    {
                        PointF p = map.Project(nova.Horizontal);
                        if (!map.IsOutOfScreen(p))
                        {
                            DrawStarName(map, p, nova, diam);
                        }
                    }
                }
            }
        }
コード例 #4
0
ファイル: IMapContext.cs プロジェクト: silas1037/Astrarium
        /// <summary>
        /// Gets drawing rotation of image, measured clockwise from
        /// a point oriented to top of the screen towards North ecliptic pole point
        /// </summary>
        /// <param name="ecl">Ecliptical coordinates of a central point of a body.</param>
        /// <returns></returns>
        public static float GetRotationTowardsEclipticPole(this IMapContext map, CrdsEcliptical ecl)
        {
            // Coordinates of center of a body (image) to be rotated
            PointF p = map.Project(ecl.ToEquatorial(map.Epsilon).ToHorizontal(map.GeoLocation, map.SiderealTime));

            // Point directed to North ecliptic pole
            PointF pNorth = map.Project((ecl + new CrdsEcliptical(0, 1)).ToEquatorial(map.Epsilon).ToHorizontal(map.GeoLocation, map.SiderealTime));

            // Clockwise rotation
            return(LineInclinationY(p, pNorth));
        }
コード例 #5
0
ファイル: IMapContext.cs プロジェクト: silas1037/Astrarium
        /// <summary>
        /// Gets drawing rotation of image, measured clockwise from
        /// a point oriented to top of the screen towards North celestial pole point
        /// </summary>
        /// <param name="eq">Equatorial coordinates of a central point of a body.</param>
        /// <returns></returns>
        public static float GetRotationTowardsNorth(this IMapContext map, CrdsEquatorial eq)
        {
            // Coordinates of center of a body (image) to be rotated
            PointF p = map.Project(eq.ToHorizontal(map.GeoLocation, map.SiderealTime));

            // Point directed to North celestial pole
            PointF pNorth = map.Project((eq + new CrdsEquatorial(0, 1)).ToHorizontal(map.GeoLocation, map.SiderealTime));

            // Clockwise rotation
            return(LineInclinationY(p, pNorth));
        }
コード例 #6
0
ファイル: TrackRenderer.cs プロジェクト: t9mike/ADK
        private void DrawLabels(IMapContext map, Track track)
        {
            var    brushLabel = new SolidBrush(track.Color);
            double trackStep  = track.Step;
            double stepLabels = track.LabelsStep.TotalDays;
            double coeff      = map.DiagonalCoefficient();

            int each = (int)(stepLabels / trackStep);

            double jd = track.From;

            for (int i = 0; i < track.Points.Count; i++)
            {
                if (i % each == 0 || i == track.Points.Count - 1)
                {
                    var    tp = track.Points[i];
                    double ad = Angle.Separation(tp.Horizontal, map.Center);
                    if (ad < map.ViewAngle * coeff)
                    {
                        PointF p = map.Project(tp.Horizontal);
                        if (!map.IsOutOfScreen(p))
                        {
                            map.Graphics.FillEllipse(brushLabel, p.X - 2, p.Y - 2, 4, 4);
                            map.DrawObjectCaption(fontLabel, brushLabel, Formatters.DateTime.Format(new Date(jd, map.GeoLocation.UtcOffset)), p, 4);
                        }
                    }
                }

                jd += trackStep;
            }
        }
コード例 #7
0
        public static float Rotate(this IMapContext map, PointF p, CrdsEquatorial eq, double PA)
        {
            // Point directed to North celestial pole
            PointF pNorth = map.Project((eq + new CrdsEquatorial(0, 1)).ToHorizontal(map.GeoLocation, map.SiderealTime));

            // Clockwise rotation
            float inc = LineInclinationY(p, pNorth);

            if (map.IsInverted)
            {
                inc = -90 - inc;
            }

            float rotation = (float)(inc - (map.IsMirrored ? -1 : 1) * PA);

            if (map.IsInverted)
            {
                rotation = 90 - rotation;
            }

            map.Graphics.TranslateTransform(p.X, p.Y);
            map.Graphics.RotateTransform(rotation);

            return(rotation);
        }
コード例 #8
0
ファイル: SolarSystemRenderer.cs プロジェクト: t9mike/ADK
        private void DrawHalo(IMapContext map)
        {
            int   size    = (int)(map.DayLightFactor * 100);
            float sunSize = map.GetDiskSize(sun.Semidiameter);
            int   alpha   = (int)(map.DayLightFactor * (1 - sunSize / (2 * size)) * 255);

            if (settings.Get <bool>("Ground") && size > 0 && alpha > 0 && 2 * size > sunSize)
            {
                bool isEclipse = sun.Horizontal.Altitude > 0 && map.DayLightFactor < 1;

                using (var halo = new GraphicsPath())
                {
                    PointF p = map.Project(sun.Horizontal);
                    halo.AddEllipse(p.X - size, p.Y - size, 2 * size, 2 * size);

                    Region reg = new Region(halo);

                    using (GraphicsPath gpMoon = new GraphicsPath())
                    {
                        if (isEclipse)
                        {
                            PointF pMoon  = map.Project(moon.Horizontal);
                            float  szMoon = map.GetDiskSize(moon.Semidiameter, 10) / 2;
                            gpMoon.AddEllipse(pMoon.X - szMoon, pMoon.Y - szMoon, 2 * szMoon, 2 * szMoon);
                            reg.Exclude(gpMoon);
                        }

                        var brush = new PathGradientBrush(halo);
                        brush.CenterPoint    = p;
                        brush.CenterColor    = Color.FromArgb(alpha, clrSunDaylight);
                        brush.SurroundColors = new Color[] { Color.Transparent };

                        map.Graphics.FillRegion(brush, reg);

                        if (isEclipse)
                        {
                            map.Graphics.FillPath(new SolidBrush(Color.FromArgb((int)(alpha * map.DayLightFactor), brush.CenterColor)), gpMoon);
                        }
                    }
                }
            }
        }
コード例 #9
0
            protected virtual GraphicsPath DrawOutline(IMapContext map, ICollection <CelestialPoint> outline)
            {
                using (GraphicsPath gp = new GraphicsPath(FillMode.Winding))
                {
                    for (int i = 0; i < outline.Count - 1; i++)
                    {
                        var h1 = outline.ElementAt(i).Horizontal;
                        var h2 = outline.ElementAt(i + 1).Horizontal;

                        PointF p1, p2;
                        p1 = map.Project(h1);
                        p2 = map.Project(h2);
                        gp.AddLine(p1, p2);
                    }

                    map.Graphics.DrawPath(Renderer.penOutlineSolid, gp);

                    return(gp);
                }
            }
コード例 #10
0
ファイル: Tycho2Renderer.cs プロジェクト: silas1037/Astrarium
        public override void Render(IMapContext map)
        {
            Graphics g          = map.Graphics;
            bool     isGround   = settings.Get <bool>("Ground");
            bool     isLabels   = settings.Get <bool>("StarsLabels");
            Brush    brushNames = new SolidBrush(map.GetColor("ColorStarsLabels"));

            if (map.MagLimit > 8 && settings.Get <bool>("Stars") && settings.Get <bool>("Tycho2"))
            {
                Brush brushStar = GetColor(map);

                PrecessionalElements pe = Precession.ElementsFK5(map.JulianDay, Date.EPOCH_J2000);

                var eq0 = map.Center.ToEquatorial(map.GeoLocation, map.SiderealTime);

                CrdsEquatorial eq = Precession.GetEquatorialCoordinates(eq0, pe);

                SkyContext context = new SkyContext(map.JulianDay, map.GeoLocation);

                tycho2.LockedStar   = map.LockedObject as Tycho2Star;
                tycho2.SelectedStar = map.SelectedObject as Tycho2Star;

                var stars = tycho2.GetStars(context, eq, map.ViewAngle, m => MagFilter(map, m));

                foreach (var star in stars)
                {
                    if (!isGround || star.Horizontal.Altitude > 0)
                    {
                        PointF p = map.Project(star.Horizontal);
                        if (!map.IsOutOfScreen(p))
                        {
                            float size = map.GetPointSize(star.Magnitude);

                            if (map.Schema == ColorSchema.White)
                            {
                                g.FillEllipse(Brushes.White, p.X - size / 2 - 1, p.Y - size / 2 - 1, size + 2, size + 2);
                            }
                            g.FillEllipse(brushStar, p.X - size / 2, p.Y - size / 2, size, size);

                            if (isLabels && map.ViewAngle < 1 && size > 3)
                            {
                                map.DrawObjectCaption(fontNames, brushNames, star.ToString(), p, size);
                            }
                            map.AddDrawnObject(star);
                        }
                    }
                }
            }
        }
コード例 #11
0
 private void DrawHorizontalPoles(IMapContext map)
 {
     if (settings.Get <bool>("LabelHorizontalPoles"))
     {
         for (int i = 0; i < 2; i++)
         {
             if (Angle.Separation(horizontalPoles[i], map.Center) < map.ViewAngle)
             {
                 PointF p = map.Project(horizontalPoles[i]);
                 map.Graphics.DrawXCross(penGridHorizontal, p, 3);
                 map.Graphics.DrawString(horizontalLabels[i], SystemFonts.DefaultFont, penGridHorizontal.Brush, p.X + 5, p.Y + 5);
             }
         }
     }
 }
コード例 #12
0
        public override void Render(IMapContext map)
        {
            Graphics g                  = map.Graphics;
            bool     isGround           = settings.Get <bool>("Ground");
            bool     showMeteors        = settings.Get("Meteors");
            bool     onlyActive         = settings.Get("MeteorsOnlyActive");
            bool     showLabels         = settings.Get("MeteorsLabels");
            int      activityClassLimit = 4;

            if (!showMeteors)
            {
                return;
            }

            var meteors = calc.GetCelestialObjects().Where(m => Angle.Separation(map.Center, m.Horizontal) < map.ViewAngle);

            if (isGround)
            {
                meteors = meteors.Where(m => m.Horizontal.Altitude >= 0);
            }

            if (onlyActive)
            {
                meteors = meteors.Where(m => m.IsActive);
            }

            meteors = meteors.Where(m => m.ActivityClass <= activityClassLimit);

            var color = map.GetColor("ColorMeteors");
            var pen   = new Pen(color);
            var brush = new SolidBrush(color);
            var font  = settings.Get <Font>("MeteorsLabelsFont");

            foreach (var meteor in meteors)
            {
                PointF p = map.Project(meteor.Horizontal);
                if (!map.IsOutOfScreen(p))
                {
                    g.DrawXCross(pen, p, 5);
                    map.AddDrawnObject(meteor);

                    if (showLabels)
                    {
                        map.DrawObjectCaption(font, brush, meteor.Name, p, 10);
                    }
                }
            }
        }
コード例 #13
0
 private void DrawEquatorialPoles(IMapContext map)
 {
     if (settings.Get <bool>("LabelEquatorialPoles"))
     {
         double coeff = map.DiagonalCoefficient();
         for (int i = 0; i < 2; i++)
         {
             var h = GridEquatorial.ToHorizontal(polePoints[i], map);
             if (Angle.Separation(h, map.Center) < map.ViewAngle * coeff)
             {
                 PointF p = map.Project(h);
                 map.Graphics.DrawXCross(penGridEquatorial, p, 3);
                 map.Graphics.DrawString(equatorialLabels[i], SystemFonts.DefaultFont, penGridEquatorial.Brush, p.X + 5, p.Y + 5);
             }
         }
     }
 }
コード例 #14
0
ファイル: SolarSystemRenderer.cs プロジェクト: t9mike/ADK
        private void RenderJupiterShadow(IMapContext map, JupiterMoon moon)
        {
            Planet jupiter = planetsCalc.Planets.ElementAt(Planet.JUPITER - 1);

            float rotation = map.GetRotationTowardsNorth(jupiter.Equatorial) + 360 - (float)jupiter.Appearance.P;

            float diam      = map.GetDiskSize(jupiter.Semidiameter);
            float diamEquat = diam;
            float diamPolar = (1 - jupiter.Flattening) * diam;

            // Jupiter radius, in pixels
            float sd = diam / 2;

            // Center of eclipsed moon
            PointF pMoon = map.Project(moon.Horizontal);

            // elipsed moon size, in pixels
            float szB = map.GetDiskSize(moon.Semidiameter);

            // Center of shadow
            PointF p = new PointF(-(float)moon.RectangularS.X * sd, (float)moon.RectangularS.Y * sd);

            map.Graphics.TranslateTransform(pMoon.X, pMoon.Y);
            map.Graphics.RotateTransform(rotation);

            var gpM = new GraphicsPath();
            var gpU = new GraphicsPath();

            gpU.AddEllipse(p.X - diamEquat / 2 - 1, p.Y - diamPolar / 2 - 1, diamEquat + 2, diamPolar + 2);
            gpM.AddEllipse(-szB / 2 - 0.5f, -szB / 2 - 0.5f, szB + 1, szB + 1);

            var regionU = new Region(gpU);

            regionU.Intersect(gpM);

            if (!regionU.IsEmpty(map.Graphics))
            {
                map.Graphics.FillRegion(new SolidBrush(clrJupiterShadow), regionU);
            }

            map.Graphics.ResetTransform();
            if (!regionU.IsEmpty(map.Graphics))
            {
                map.DrawObjectCaption(fontShadowLabel, brushShadowLabel, Text.Get("EclipsedByJupiter"), pMoon, szB);
            }
        }
コード例 #15
0
ファイル: ConstellationsRenderer.cs プロジェクト: t9mike/ADK
        /// <summary>
        /// Renders constellations labels on the map
        /// </summary>
        private void RenderConstLabels(IMapContext map)
        {
            var    constellations = constellationsCalc.ConstLabels;
            bool   isGround       = settings.Get <bool>("Ground");
            double coeff          = map.DiagonalCoefficient();

            StringFormat format = new StringFormat();

            format.LineAlignment = StringAlignment.Center;
            format.Alignment     = StringAlignment.Center;

            int       fontSize   = Math.Min((int)(800 / map.ViewAngle), 32);
            Font      font       = new Font(FontFamily.GenericSansSerif, fontSize);
            LabelType labelType  = settings.Get <LabelType>("ConstLabelsType");
            Brush     brushLabel = new SolidBrush(map.GetColor("ColorConstLabels"));

            foreach (var c in constellations)
            {
                var h = c.Horizontal;
                if ((!isGround || h.Altitude > 0) && Angle.Separation(map.Center, h) < map.ViewAngle * coeff)
                {
                    var    p             = map.Project(h);
                    var    constellation = GetConstellation(c.Code);
                    string label;
                    switch (labelType)
                    {
                    case LabelType.InternationalCode:
                        label = constellation.Code;
                        break;

                    case LabelType.LocalName:
                        label = constellation.LocalName;
                        break;

                    case LabelType.InternationalName:
                    default:
                        label = constellation.LatinName;
                        break;
                    }

                    map.Graphics.DrawString(label, font, brushLabel, p, format);
                }
            }
        }
コード例 #16
0
        private void DrawEquinoxLabels(IMapContext map)
        {
            if (settings.Get <bool>("LabelEquinoxPoints"))
            {
                for (int i = 0; i < 2; i++)
                {
                    var h = LineEcliptic.ToHorizontal(LineEcliptic.Column(equinoxRA[i]).ElementAt(0), map);
                    if (Angle.Separation(h, map.Center) < map.ViewAngle)
                    {
                        PointF p = map.Project(h);

                        var hint = map.Graphics.TextRenderingHint;
                        map.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
                        map.Graphics.DrawStringOpaque(equinoxLabels[i], fontEquinoxLabel, penLineEcliptic.Brush, new SolidBrush(map.GetSkyColor()), p);
                        map.Graphics.TextRenderingHint = hint;
                    }
                }
            }
        }
コード例 #17
0
        public override void Render(IMapContext map)
        {
            if (settings.Get <bool>("MilkyWay"))
            {
                int alpha = Math.Min((int)(k * map.ViewAngle + b), 255);
                if (alpha > maxAlpha)
                {
                    var smoothing = map.Graphics.SmoothingMode;
                    map.Graphics.SmoothingMode = SmoothingMode.None;

                    if (map.Schema == ColorSchema.Day)
                    {
                        alpha = (int)(alpha * (1 - map.DayLightFactor));
                    }

                    for (int i = 0; i < milkyWayCalc.MilkyWay.Count(); i++)
                    {
                        var points = new List <PointF>();

                        for (int j = 0; j < milkyWayCalc.MilkyWay[i].Count; j++)
                        {
                            var    h  = milkyWayCalc.MilkyWay[i][j].Horizontal;
                            double ad = Angle.Separation(h, map.Center);

                            // 130 degrees value limit has been chosen experimentally
                            if (ad < 130)
                            {
                                points.Add(map.Project(h));
                            }
                        }

                        if (points.Count >= 3)
                        {
                            Color color = Color.FromArgb(alpha, map.GetColor("ColorMilkyWay"));
                            map.Graphics.FillPolygon(new SolidBrush(color), points.ToArray(), FillMode.Winding);
                        }
                    }

                    map.Graphics.SmoothingMode = smoothing;
                }
            }
        }
コード例 #18
0
        private void DrawEquinoxLabels(IMapContext map)
        {
            if (settings.Get <bool>("LabelEquinoxPoints"))
            {
                double coeff = map.DiagonalCoefficient();
                for (int i = 0; i < 2; i++)
                {
                    var h = LineEcliptic.ToHorizontal(LineEcliptic.Column(equinoxRA[i]).ElementAt(0), map);
                    if (Angle.Separation(h, map.Center) < map.ViewAngle * coeff)
                    {
                        PointF p = map.Project(h);

                        var hint = map.Graphics.TextRenderingHint;
                        map.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
                        map.Graphics.DrawStringOpaque(equinoxLabels[i], fontEquinoxLabel, penLineEcliptic.Brush, Brushes.Black, p);
                        map.Graphics.TextRenderingHint = hint;
                    }
                }
            }
        }
コード例 #19
0
        public override void Render(IMapContext map)
        {
            if (ascom.IsConnected)
            {
                try
                {
                    var hor = ascom.Position.ToHorizontal(map.GeoLocation, map.SiderealTime);
                    var p   = map.Project(hor);

                    var color  = map.GetColor("TelescopeMarkerColor");
                    Pen marker = new Pen(color, 2);
                    marker.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;

                    float r  = 16;
                    float a0 = (float)(Math.PI / 4);
                    for (double a = 0; a < 2 * Math.PI; a += Math.PI / 2)
                    {
                        float x0 = p.X + (r / 2) * (float)Math.Cos(a + a0);
                        float y0 = p.Y + (r / 2) * (float)Math.Sin(a + a0);

                        float x1 = p.X + r * (float)Math.Cos(a + a0);
                        float y1 = p.Y + r * (float)Math.Sin(a + a0);

                        map.Graphics.DrawLine(marker, new PointF(x0, y0), new PointF(x1, y1));
                    }
                    map.Graphics.DrawEllipse(marker, p.X - 16, p.Y - 16, 32, 32);

                    if (settings.Get("TelescopeMarkerLabel"))
                    {
                        var font  = settings.Get <Font>("TelescopeMarkerFont");
                        var brush = new SolidBrush(map.GetColor("TelescopeMarkerColor"));
                        map.Graphics.DrawString(ascom.TelescopeName, font, brush, new PointF(p.X + 16 * 0.8f, p.Y + 16 * 0.8f));
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError($"Rendering error in {nameof(TelescopeRenderer)}: {ex}");
                }
            }
        }
コード例 #20
0
        public static void Rotate(this IMapContext map, PointF p, CrdsEcliptical ecl)
        {
            // Point directed to North ecliptic pole
            PointF pNorth = map.Project((ecl + new CrdsEcliptical(0, 1)).ToEquatorial(map.Epsilon).ToHorizontal(map.GeoLocation, map.SiderealTime));

            // Clockwise rotation
            float inc = LineInclinationY(p, pNorth);

            if (map.IsInverted)
            {
                inc = -90 - inc;
            }
            float rotation = (float)inc;

            if (map.IsInverted)
            {
                rotation = 90 - rotation;
            }

            map.Graphics.TranslateTransform(p.X, p.Y);
            map.Graphics.RotateTransform(rotation);
        }
コード例 #21
0
        private void DrawLunarNodes(IMapContext map)
        {
            if (settings.Get <bool>("LabelLunarNodes"))
            {
                double ascNode = LunarEphem.TrueAscendingNode(map.JulianDay);

                for (int i = 0; i < 2; i++)
                {
                    var h = LineEcliptic.ToHorizontal(new GridPoint(ascNode + (i > 0 ? 180 : 0), 0), map);
                    if (Angle.Separation(h, map.Center) < map.ViewAngle)
                    {
                        PointF p = map.Project(h);

                        var hint = map.Graphics.TextRenderingHint;
                        map.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
                        map.Graphics.FillEllipse(penLineEcliptic.Brush, p.X - 1.5f, p.Y - 1.5f, 3, 3);
                        map.Graphics.DrawStringOpaque(nodesLabels[i], fontNodeLabel, penLineEcliptic.Brush, new SolidBrush(map.GetSkyColor()), p);
                        map.Graphics.TextRenderingHint = hint;
                    }
                }
            }
        }
コード例 #22
0
ファイル: SolarSystemRenderer.cs プロジェクト: t9mike/ADK
        private void RenderJupiterMoons(IMapContext map, Planet jupiter, IEnumerable <JupiterMoon> moons)
        {
            bool   isGround    = settings.Get <bool>("Ground");
            bool   useTextures = settings.Get <bool>("UseTextures");
            double coeff       = map.DiagonalCoefficient();

            foreach (var moon in moons)
            {
                double ad = Angle.Separation(moon.Horizontal, map.Center);

                if ((!isGround || moon.Horizontal.Altitude + moon.Semidiameter / 3600 > 0) &&
                    ad < coeff * map.ViewAngle + moon.Semidiameter / 3600)
                {
                    PointF p        = map.Project(moon.Horizontal);
                    PointF pJupiter = map.Project(jupiter.Horizontal);

                    float size = map.GetPointSize(moon.Magnitude, 2);
                    float diam = map.GetDiskSize(moon.Semidiameter);

                    // diameter is to small to render moon disk,
                    // but point size caclulated from magnitude is enough to be drawn
                    if (size > diam && (int)size > 0)
                    {
                        // do not draw moon point if eclipsed
                        if (!moon.IsEclipsedByJupiter)
                        {
                            // satellite is distant enough from the Jupiter
                            // but too small to be drawn as disk
                            if (map.DistanceBetweenPoints(p, pJupiter) >= 5)
                            {
                                map.Graphics.TranslateTransform(p.X, p.Y);
                                map.Graphics.FillEllipse(new SolidBrush(map.GetColor(Color.Wheat)), -size / 2, -size / 2, size, size);
                                map.Graphics.ResetTransform();

                                map.DrawObjectCaption(fontLabel, brushLabel, moon.Name, p, 2);
                                map.AddDrawnObject(moon);
                            }
                        }
                    }
                    // moon should be rendered as disk
                    else if (diam >= size && (int)diam > 0)
                    {
                        float rotation = map.GetRotationTowardsNorth(jupiter.Equatorial) + 360 - (float)jupiter.Appearance.P;

                        map.Graphics.TranslateTransform(p.X, p.Y);
                        map.Graphics.RotateTransform(rotation);

                        if (useTextures)
                        {
                            Image texture = imagesCache.RequestImage($"5-{moon.Number}", new PlanetTextureToken($"5-{moon.Number}", moon.CM, jupiter.Appearance.D), PlanetTextureProvider, map.Redraw);
                            if (texture != null)
                            {
                                map.DrawImage(texture, -diam / 2 * 1.01f, -diam / 2 * 1.01f, diam * 1.01f, diam * 1.01f);
                                DrawVolume(map, diam, 0);
                            }
                            else
                            {
                                map.Graphics.FillEllipse(new SolidBrush(map.GetColor(Color.Wheat)), -diam / 2, -diam / 2, diam, diam);
                            }
                        }
                        else
                        {
                            map.Graphics.FillEllipse(new SolidBrush(map.GetColor(Color.Wheat)), -diam / 2, -diam / 2, diam, diam);
                            if (diam > 2)
                            {
                                map.Graphics.DrawEllipse(new Pen(map.GetSkyColor()), -diam / 2, -diam / 2, diam, diam);
                            }
                        }

                        map.Graphics.ResetTransform();

                        // render another moon shadows on the moon
                        RenderJupiterMoonShadow(map, moon, moon.RectangularS);

                        // render Jupiter shadow on the moon
                        if (moon.IsEclipsedByJupiter)
                        {
                            RenderJupiterShadow(map, moon);
                        }

                        map.DrawObjectCaption(fontLabel, brushLabel, moon.Name, p, diam);
                        map.AddDrawnObject(moon);
                    }
                }
            }
        }
コード例 #23
0
ファイル: CometsRenderer.cs プロジェクト: silas1037/Astrarium
        public override void Render(IMapContext map)
        {
            Graphics g           = map.Graphics;
            var      allComets   = cometsCalc.Comets;
            bool     isGround    = settings.Get("Ground");
            bool     useTextures = settings.Get("PlanetsTextures");
            bool     drawComets  = settings.Get("Comets");
            bool     drawLabels  = settings.Get("AsteroidsLabels");
            Brush    brushNames  = new SolidBrush(map.GetColor("ColorCometsLabels"));

            if (drawComets)
            {
                var comets = allComets.Where(a => Angle.Separation(map.Center, a.Horizontal) < map.ViewAngle);

                foreach (var c in comets)
                {
                    float diam = map.GetDiskSize(c.Semidiameter);

                    if (diam > 5)
                    {
                        double ad = Angle.Separation(c.Horizontal, map.Center);

                        if ((!isGround || c.Horizontal.Altitude + c.Semidiameter / 3600 > 0) &&
                            ad < map.ViewAngle + c.Semidiameter / 3600)
                        {
                            PointF p = map.Project(c.Horizontal);
                            PointF t = map.Project(c.TailHorizontal);

                            double tail = map.DistanceBetweenPoints(p, t);

                            if (diam > 5 || tail > 10)
                            {
                                using (var gpComet = new GraphicsPath())
                                {
                                    double rotation = Math.Atan2(t.Y - p.Y, t.X - p.X) + Math.PI / 2;
                                    gpComet.StartFigure();

                                    // tail is long enough
                                    if (tail > diam)
                                    {
                                        gpComet.AddArc(p.X - diam / 2, p.Y - diam / 2, diam, diam, (float)Angle.ToDegrees(rotation), 180);
                                        gpComet.AddLines(new PointF[] { gpComet.PathPoints[gpComet.PathPoints.Length - 1], t, gpComet.PathPoints[0] });
                                    }
                                    // draw coma only
                                    else
                                    {
                                        gpComet.AddEllipse(p.X - diam / 2, p.Y - diam / 2, diam, diam);
                                    }

                                    gpComet.CloseAllFigures();
                                    using (var brushComet = new PathGradientBrush(gpComet))
                                    {
                                        brushComet.CenterPoint = p;
                                        int alpha = 100;
                                        if (c.Magnitude >= map.MagLimit)
                                        {
                                            alpha -= (int)(100 * (c.Magnitude - map.MagLimit) / c.Magnitude);
                                        }
                                        brushComet.CenterColor    = map.GetColor(Color.FromArgb(alpha, colorComet));
                                        brushComet.SurroundColors = gpComet.PathPoints.Select(pp => Color.Transparent).ToArray();
                                        g.FillPath(brushComet, gpComet);
                                    }
                                }

                                if (drawLabels)
                                {
                                    var font = settings.Get <Font>("CometsLabelsFont");
                                    map.DrawObjectCaption(font, brushNames, c.Name, p, diam);
                                }
                                map.AddDrawnObject(c);
                            }
                        }
                    }
                }
            }
        }
コード例 #24
0
            public virtual void Draw(IMapContext map, ISettings settings, DeepSky ds)
            {
                PointF p = map.Project(ds.Horizontal);

                float sizeA = GetDiameter(map, ds.SizeA);
                float sizeB = GetDiameter(map, ds.SizeB);

                // elliptic object with known size
                if (sizeB > 0 && sizeB != sizeA)
                {
                    float diamA = GetDiameter(map, ds.SizeA);
                    if (diamA > 10)
                    {
                        float diamB = GetDiameter(map, ds.SizeB);
                        if (ds.Outline != null && settings.Get <bool>("DeepSkyOutlines"))
                        {
                            DrawOutline(map, ds.Outline);
                        }
                        else
                        {
                            float rotation = map.GetRotationTowardsNorth(ds.Equatorial) + 90 - ds.PA;
                            map.Graphics.TranslateTransform(p.X, p.Y);
                            map.Graphics.RotateTransform(rotation);
                            DrawEllipticObject(map.Graphics, diamA, diamB);
                            map.Graphics.ResetTransform();
                        }
                        map.AddDrawnObject(ds);

                        if (map.ViewAngle <= Renderer.limitLabels && settings.Get <bool>("DeepSkyLabels"))
                        {
                            var font = settings.Get <Font>("DeepSkyLabelsFont");
                            map.DrawObjectCaption(font, Renderer.brushCaption, ds.DisplayName, p, Math.Min(diamA, diamB));
                        }
                    }
                }
                // round object
                else if (sizeA > 0)
                {
                    float diamA = GetDiameter(map, ds.SizeA);
                    if (diamA > 10)
                    {
                        if (ds.Outline != null && settings.Get <bool>("DeepSkyOutlines"))
                        {
                            DrawOutline(map, ds.Outline);
                        }
                        else
                        {
                            float rotation = map.GetRotationTowardsNorth(ds.Equatorial) + 90 - ds.PA;
                            map.Graphics.TranslateTransform(p.X, p.Y);
                            map.Graphics.RotateTransform(rotation);
                            DrawRoundObject(map.Graphics, diamA);
                            map.Graphics.ResetTransform();
                        }
                        map.AddDrawnObject(ds);

                        if (map.ViewAngle <= Renderer.limitLabels && settings.Get <bool>("DeepSkyLabels"))
                        {
                            var font = settings.Get <Font>("DeepSkyLabelsFont");
                            map.DrawObjectCaption(font, Renderer.brushCaption, ds.DisplayName, p, diamA);
                        }
                    }
                }
                // point object
                else
                {
                    float size = map.GetPointSize(ds.Mag == null ? 15 : ds.Mag.Value);
                    if ((int)size > 0)
                    {
                        if (ds.Outline != null && settings.Get <bool>("DeepSkyOutlines"))
                        {
                            DrawOutline(map, ds.Outline);
                        }
                        else
                        {
                            map.Graphics.TranslateTransform(p.X, p.Y);
                            DrawPointObject(map.Graphics, size);
                            map.Graphics.ResetTransform();
                        }
                        map.AddDrawnObject(ds);

                        if (map.ViewAngle <= Renderer.limitLabels && settings.Get <bool>("DeepSkyLabels"))
                        {
                            var font = settings.Get <Font>("DeepSkyLabelsFont");
                            map.DrawObjectCaption(font, Renderer.brushCaption, ds.DisplayName, p, 0);
                        }
                    }
                }
            }
コード例 #25
0
ファイル: SolarSystemRenderer.cs プロジェクト: t9mike/ADK
        private void RenderEarthShadow(IMapContext map)
        {
            // here and below suffixes meanings are: "M" = Moon, "P" = penumbra, "U" = umbra

            // angular distance from center of map to earth shadow center
            double ad = Angle.Separation(moon.EarthShadowCoordinates, map.Center);

            // semidiameter of penumbra in seconds of arc
            double sdP = moon.EarthShadow.PenumbraRadius * 6378.0 / 1738.0 * moon.Semidiameter;

            bool   isGround = settings.Get <bool>("Ground");
            double coeff    = map.DiagonalCoefficient();

            if ((!isGround || moon.EarthShadowCoordinates.Altitude + sdP / 3600 > 0) &&
                ad < coeff * map.ViewAngle + sdP / 3600)
            {
                PointF p     = map.Project(moon.EarthShadowCoordinates);
                PointF pMoon = map.Project(moon.Horizontal);

                // size of penumbra, in pixels
                float szP = map.GetDiskSize(sdP);

                // size of umbra, in pixels
                float szU = szP / (float)moon.EarthShadow.Ratio;

                // size of Moon, in pixels
                float szM = map.GetDiskSize(moon.Semidiameter);

                // fraction of the penumbra ring (without umbra part)
                float fr = 1 - szU / szP;

                // do not render on large view angle
                if (szM >= 10)
                {
                    // if eclipse takes place
                    if (Angle.Separation(moon.Horizontal, moon.EarthShadowCoordinates) <= sdP / 3600)
                    {
                        var gpM = new GraphicsPath();
                        var gpP = new GraphicsPath();
                        var gpU = new GraphicsPath();

                        gpP.AddEllipse(p.X - szP / 2, p.Y - szP / 2, szP, szP);
                        gpU.AddEllipse(p.X - szU / 2, p.Y - szU / 2, szU, szU);
                        gpM.AddEllipse(pMoon.X - szM / 2 - 0.5f, pMoon.Y - szM / 2 - 0.5f, szM + 1, szM + 1);

                        var brushP = new PathGradientBrush(gpP);
                        brushP.CenterPoint    = p;
                        brushP.CenterColor    = clrPenumbraGrayDark;
                        brushP.SurroundColors = new Color[] { clrPenumbraTransp };

                        var blendP = new ColorBlend();
                        blendP.Colors              = new Color[] { clrPenumbraTransp, clrPenumbraTransp, clrPenumbraGrayLight, clrPenumbraGrayDark, clrPenumbraGrayDark };
                        blendP.Positions           = new float[] { 0, fr / 2, fr * 0.95f, fr, 1 };
                        brushP.InterpolationColors = blendP;

                        var brushU = new PathGradientBrush(gpU);
                        brushU.CenterColor     = clrUmbraRed;
                        brushU.SurroundColors  = new Color[] { clrUmbraGray };
                        brushU.Blend.Factors   = new float[] { 0, 0.8f, 1 };
                        brushU.Blend.Positions = new float[] { 0, 0.8f, 1 };

                        var regionP = new Region(gpP);
                        var regionU = new Region(gpU);

                        regionP.Exclude(regionU);
                        regionP.Intersect(gpM);
                        regionU.Intersect(gpM);

                        map.Graphics.FillRegion(brushP, regionP);
                        map.Graphics.FillRegion(brushU, regionU);
                    }

                    // outline circles
                    if (settings.Get <bool>("EarthShadowOutline") && map.ViewAngle > 0.5)
                    {
                        var brush = new SolidBrush(map.GetColor(clrShadowOutline));
                        var pen   = new Pen(brush)
                        {
                            DashStyle = DashStyle.Dot
                        };

                        map.Graphics.TranslateTransform(p.X, p.Y);
                        map.Graphics.DrawEllipse(pen, -szP / 2, -szP / 2, szP, szP);
                        map.Graphics.DrawEllipse(pen, -szU / 2, -szU / 2, szU, szU);
                        map.Graphics.ResetTransform();
                        if (map.ViewAngle <= 10)
                        {
                            map.DrawObjectCaption(fontShadowLabel, brush, Text.Get("EarthShadow.Label"), p, szP);
                        }
                    }
                }
            }
        }
コード例 #26
0
ファイル: SolarSystemRenderer.cs プロジェクト: t9mike/ADK
        private void RenderPlanet(IMapContext map, Planet planet)
        {
            if (!settings.Get <bool>("Planets"))
            {
                return;
            }

            if (planet.Number == Planet.JUPITER)
            {
                // render moons behind Jupiter
                var moons = planetsCalc.JupiterMoons.Where(m => m.Rectangular.Z >= 0).OrderByDescending(m => m.Rectangular.Z);
                RenderJupiterMoons(map, planet, moons);
            }

            Graphics g           = map.Graphics;
            double   ad          = Angle.Separation(planet.Horizontal, map.Center);
            bool     isGround    = settings.Get <bool>("Ground");
            bool     useTextures = settings.Get <bool>("UseTextures");
            double   coeff       = map.DiagonalCoefficient();

            if ((!isGround || planet.Horizontal.Altitude + planet.Semidiameter / 3600 > 0) &&
                ad < coeff * map.ViewAngle + planet.Semidiameter / 3600)
            {
                float size = map.GetPointSize(planet.Magnitude, maxDrawingSize: 7);
                float diam = map.GetDiskSize(planet.Semidiameter);

                // diameter is to small to render as planet disk,
                // but point size caclulated from magnitude is enough to be drawn
                if (size > diam && (int)size > 0)
                {
                    PointF p = map.Project(planet.Horizontal);
                    g.FillEllipse(GetPlanetColor(map, planet.Number), p.X - size / 2, p.Y - size / 2, size, size);

                    map.DrawObjectCaption(fontLabel, brushLabel, planet.Name, p, size);
                    map.AddDrawnObject(planet);
                }

                // planet should be rendered as disk
                else if (diam >= size && (int)diam > 0)
                {
                    PointF p = map.Project(planet.Horizontal);

                    float rotation = map.GetRotationTowardsNorth(planet.Equatorial) + 360 - (float)planet.Appearance.P;

                    g.TranslateTransform(p.X, p.Y);
                    g.RotateTransform(rotation);

                    DrawRotationAxis(g, diam);

                    if (planet.Number == Planet.SATURN)
                    {
                        var rings = planetsCalc.SaturnRings;

                        double maxSize = Math.Max(map.Width, map.Height);

                        // scale value to convert visible size of ring to screen pixels
                        double scale = 1.0 / 3600 / map.ViewAngle * maxSize / 4;

                        // draw rings by halfs arcs, first half is farther one
                        for (int half = 0; half < 2; half++)
                        {
                            // draw planets textures
                            if (useTextures)
                            {
                                float a = (float)(rings.GetRingSize(0, RingEdge.Outer, RingAxis.Major) * scale);
                                float b = (float)(rings.GetRingSize(0, RingEdge.Outer, RingAxis.Minor) * scale);

                                // half of source image: 0 = top, 1 = bottom
                                int h = (half + (rings.B > 0 ? 0 : 1)) % 2;

                                Image textureRings = imagesCache.RequestImage("Rings", true, t => Image.FromFile("Data\\Rings.png", true), map.Redraw);
                                if (textureRings != null)
                                {
                                    map.DrawImage(textureRings,
                                                  // destination rectangle
                                                  new RectangleF(-a, -b + h * b, a * 2, b),
                                                  // source rectangle
                                                  new RectangleF(0, h * textureRings.Height / 2f, textureRings.Width, textureRings.Height / 2f));
                                }
                                else
                                {
                                    DrawRingsUntextured(g, rings, half, scale);
                                }
                            }
                            // do not use textures
                            else
                            {
                                DrawRingsUntextured(g, rings, half, scale);
                            }

                            // draw planet disk after first half of rings
                            if (half == 0)
                            {
                                DrawPlanetGlobe(map, planet, diam);
                            }
                        }
                    }
                    else
                    {
                        DrawPlanetGlobe(map, planet, diam);
                    }

                    g.ResetTransform();

                    if (planet.Number <= Planet.MARS)
                    {
                        float phase = (float)planet.Phase * Math.Sign(planet.Elongation);

                        GraphicsPath shadow = GetPhaseShadow(phase, diam + 1, planet.Flattening);

                        // rotation of phase image
                        rotation = map.GetRotationTowardsEclipticPole(planet.Ecliptical);

                        g.TranslateTransform(p.X, p.Y);
                        g.RotateTransform(rotation);
                        g.FillPath(GetShadowBrush(map), shadow);
                        g.ResetTransform();
                    }

                    map.DrawObjectCaption(fontLabel, brushLabel, planet.Name, p, diam);
                    map.AddDrawnObject(planet);

                    if (planet.Number == Planet.JUPITER)
                    {
                        // render shadows on Jupiter
                        RenderJupiterMoonShadow(map, planet);
                    }
                }
            }

            // render moons over Jupiter
            if (planet.Number == Planet.JUPITER)
            {
                var moons = planetsCalc.JupiterMoons.Where(m => m.Rectangular.Z < 0).OrderByDescending(m => m.Rectangular.Z);
                RenderJupiterMoons(map, planet, moons);
            }
        }
コード例 #27
0
ファイル: GroundRenderer.cs プロジェクト: t9mike/ADK
        public override void Render(IMapContext map)
        {
            double coeff = map.DiagonalCoefficient();

            if (settings.Get <bool>("Ground"))
            {
                const int  POINTS_COUNT = 64;
                PointF[]   hor          = new PointF[POINTS_COUNT];
                double     step         = 2 * map.ViewAngle / (POINTS_COUNT - 1);
                SolidBrush brushGround  = new SolidBrush(map.GetColor(colorGroundNight, colorGroundDay));

                // Bottom part of ground shape

                for (int i = 0; i < POINTS_COUNT; i++)
                {
                    var h = new CrdsHorizontal(map.Center.Azimuth - map.ViewAngle + step * i, 0);
                    hor[i] = map.Project(h);
                }
                if (hor[0].X >= 0)
                {
                    hor[0].X = -1;
                }
                if (hor[POINTS_COUNT - 1].X <= map.Width)
                {
                    hor[POINTS_COUNT - 1].X = map.Width + 1;
                }

                if (hor.Any(h => !map.IsOutOfScreen(h)))
                {
                    GraphicsPath gp = new GraphicsPath();

                    gp.AddCurve(hor);
                    gp.AddLines(new PointF[]
                    {
                        new PointF(map.Width + 1, map.Height + 1),
                        new PointF(-1, map.Height + 1)
                    });

                    map.Graphics.FillPath(brushGround, gp);
                }
                else if (map.Center.Altitude <= 0)
                {
                    map.Graphics.FillRectangle(brushGround, 0, 0, map.Width, map.Height);
                }

                // Top part of ground shape

                if (map.Center.Altitude > 0)
                {
                    for (int i = 0; i < POINTS_COUNT; i++)
                    {
                        var h = new CrdsHorizontal(map.Center.Azimuth - map.ViewAngle - step * i, 0);
                        hor[i] = map.Project(h);
                    }

                    if (hor.Count(h => !map.IsOutOfScreen(h)) > 2)
                    {
                        GraphicsPath gp = new GraphicsPath();

                        gp.AddCurve(hor);
                        gp.AddLines(new PointF[]
                        {
                            new PointF(map.Width + 1, -1),
                            new PointF(-1, -1),
                        });

                        map.Graphics.FillPath(brushGround, gp);
                    }
                }
            }

            if (map.Schema == ColorSchema.White || (!settings.Get <bool>("Ground") && settings.Get <bool>("HorizonLine")))
            {
                const int POINTS_COUNT = 64;
                PointF[]  hor          = new PointF[POINTS_COUNT];
                double    step         = 2 * map.ViewAngle / (POINTS_COUNT - 1);

                for (int i = 0; i < POINTS_COUNT; i++)
                {
                    var h = new CrdsHorizontal(map.Center.Azimuth - map.ViewAngle + step * i, 0);
                    hor[i] = map.Project(h);
                }
                if (hor[0].X >= 0)
                {
                    hor[0].X = -1;
                }
                if (hor[POINTS_COUNT - 1].X <= map.Width)
                {
                    hor[POINTS_COUNT - 1].X = map.Width + 1;
                }

                if (hor.Any(h => !map.IsOutOfScreen(h)))
                {
                    Pen penHorizonLine = new Pen(map.GetColor("ColorHorizon"), 2);
                    map.Graphics.DrawCurve(penHorizonLine, hor);
                }
            }

            if (settings.Get <bool>("LabelCardinalDirections"))
            {
                Brush        brushCardinalLabels = new SolidBrush(map.GetColor("ColorCardinalDirections"));
                StringFormat format = new StringFormat()
                {
                    LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Center
                };
                for (int i = 0; i < cardinalDirections.Length; i++)
                {
                    var h = new CrdsHorizontal(i * 360 / cardinalDirections.Length, 0);
                    if (Angle.Separation(h, map.Center) < map.ViewAngle * coeff)
                    {
                        PointF p = map.Project(h);
                        p.Y += fontCardinalLabels[i % 2].Height;
                        using (var gp = new GraphicsPath())
                        {
                            map.Graphics.DrawString(Text.Get($"CardinalDirections.{cardinalDirections[i]}"), fontCardinalLabels[i % 2], brushCardinalLabels, p, format);
                        }
                    }
                }
            }
        }
コード例 #28
0
        public override void Render(IMapContext map)
        {
            Graphics g               = map.Graphics;
            var      allComets       = cometsCalc.Comets;
            bool     isGround        = settings.Get("Ground");
            bool     useTextures     = settings.Get("PlanetsTextures");
            bool     drawComets      = settings.Get("Comets");
            bool     drawLabels      = settings.Get("CometsLabels");
            bool     drawAll         = settings.Get <bool>("CometsDrawAll");
            decimal  drawAllMagLimit = settings.Get <decimal>("CometsDrawAllMagLimit");
            bool     drawLabelMag    = settings.Get <bool>("CometsLabelsMag");
            Brush    brushNames      = new SolidBrush(map.GetColor("ColorCometsLabels"));
            var      font            = settings.Get <Font>("CometsLabelsFont");

            if (drawComets)
            {
                var comets = allComets.Where(a => Angle.Separation(map.Center, a.Horizontal) < map.ViewAngle);

                foreach (var c in comets)
                {
                    float diam = map.GetDiskSize(c.Semidiameter);
                    float size = map.GetPointSize(c.Magnitude);

                    // if "draw all" setting is enabled, draw comets brighter than limit
                    if (drawAll && size < 1 && c.Magnitude <= (float)drawAllMagLimit)
                    {
                        size = 1;
                    }

                    string label = drawLabelMag ? $"{c.Name} {Formatters.Magnitude.Format(c.Magnitude)}" : c.Name;

                    if (diam > 5)
                    {
                        double ad = Angle.Separation(c.Horizontal, map.Center);

                        if ((!isGround || c.Horizontal.Altitude + c.Semidiameter / 3600 > 0) &&
                            ad < map.ViewAngle + c.Semidiameter / 3600)
                        {
                            PointF p = map.Project(c.Horizontal);
                            PointF t = map.Project(c.TailHorizontal);

                            double tail = map.DistanceBetweenPoints(p, t);

                            if (diam > 5 || tail > 10)
                            {
                                using (var gpComet = new GraphicsPath())
                                {
                                    double rotation = Math.Atan2(t.Y - p.Y, t.X - p.X) + Math.PI / 2;
                                    gpComet.StartFigure();

                                    // tail is long enough
                                    if (tail > diam)
                                    {
                                        gpComet.AddArc(p.X - diam / 2, p.Y - diam / 2, diam, diam, (float)Angle.ToDegrees(rotation), 180);
                                        gpComet.AddLines(new PointF[] { gpComet.PathPoints[gpComet.PathPoints.Length - 1], t, gpComet.PathPoints[0] });
                                    }
                                    // draw coma only
                                    else
                                    {
                                        gpComet.AddEllipse(p.X - diam / 2, p.Y - diam / 2, diam, diam);
                                    }

                                    gpComet.CloseAllFigures();
                                    using (var brushComet = new PathGradientBrush(gpComet))
                                    {
                                        brushComet.CenterPoint = p;
                                        int alpha = 100;
                                        if (c.Magnitude >= map.MagLimit)
                                        {
                                            alpha -= (int)(100 * (c.Magnitude - map.MagLimit) / c.Magnitude);
                                        }
                                        brushComet.CenterColor    = map.GetColor(Color.FromArgb(alpha, colorComet));
                                        brushComet.SurroundColors = gpComet.PathPoints.Select(pp => Color.Transparent).ToArray();
                                        g.FillPath(brushComet, gpComet);
                                    }
                                }

                                if (drawLabels)
                                {
                                    map.DrawObjectCaption(font, brushNames, label, p, diam);
                                }
                                map.AddDrawnObject(c);
                            }
                        }
                    }
                    else if ((int)size > 0)
                    {
                        PointF p = map.Project(c.Horizontal);

                        if (!map.IsOutOfScreen(p))
                        {
                            g.FillEllipse(new SolidBrush(map.GetColor(Color.White)), p.X - size / 2, p.Y - size / 2, size, size);

                            if (drawLabels)
                            {
                                map.DrawObjectCaption(font, brushNames, label, p, size);
                            }

                            map.AddDrawnObject(c);
                            continue;
                        }
                    }
                }
            }
        }
コード例 #29
0
ファイル: SolarSystemRenderer.cs プロジェクト: t9mike/ADK
        private void RenderJupiterMoonShadow(IMapContext map, SizeableCelestialObject eclipsedBody, CrdsRectangular rect = null)
        {
            if (rect == null)
            {
                rect = new CrdsRectangular();
            }

            // collect moons than can produce a shadow
            var ecliptingMoons = planetsCalc.JupiterMoons.Where(m => m.RectangularS.Z < rect.Z);

            if (ecliptingMoons.Any())
            {
                Planet jupiter = planetsCalc.Planets.ElementAt(Planet.JUPITER - 1);

                float rotation = map.GetRotationTowardsNorth(jupiter.Equatorial) + 360 - (float)jupiter.Appearance.P;

                // Jupiter radius, in pixels
                float sd = map.GetDiskSize(jupiter.Semidiameter) / 2;

                // Center of eclipsed body
                PointF pBody = map.Project(eclipsedBody.Horizontal);

                // elipsed body size, in pixels
                float szB = map.GetDiskSize(eclipsedBody.Semidiameter);

                foreach (var moon in ecliptingMoons)
                {
                    // umbra and penumbra radii, in acrseconds
                    var shadow = GalileanMoons.Shadow(jupiter.Ecliptical.Distance, jupiter.DistanceFromSun, moon.Number - 1, moon.RectangularS, rect);

                    // umbra and penumbra size, in pixels
                    float szU = map.GetDiskSize(shadow.Umbra);
                    float szP = map.GetDiskSize(shadow.Penumbra);

                    // coordinates of shadow relative to eclipsed body
                    CrdsRectangular shadowRelative = moon.RectangularS - rect;

                    // Center of shadow
                    PointF p = new PointF((float)shadowRelative.X * sd, -(float)shadowRelative.Y * sd);

                    map.Graphics.TranslateTransform(pBody.X, pBody.Y);
                    map.Graphics.RotateTransform(rotation);

                    // shadow has enough size to be rendered
                    if ((int)szP > 0)
                    {
                        var gpB = new GraphicsPath();
                        var gpP = new GraphicsPath();
                        var gpU = new GraphicsPath();

                        gpU.AddEllipse(p.X - szU / 2, p.Y - szU / 2, szU, szU);
                        gpP.AddEllipse(p.X - szP / 2, p.Y - szP / 2, szP, szP);
                        gpB.AddEllipse(-szB / 2 - 0.5f, -szB / 2 - 0.5f, szB + 1, szB + 1);

                        var regionP = new Region(gpP);
                        regionP.Intersect(gpB);

                        if (!regionP.IsEmpty(map.Graphics))
                        {
                            float f1 = 1 - (szU + szP) / 2 / szP;
                            float f2 = 1 - szU / szP;

                            var brushP = new PathGradientBrush(gpP);
                            brushP.CenterPoint = p;
                            brushP.CenterColor = clrJupiterMoonShadowLight;

                            brushP.InterpolationColors = new ColorBlend()
                            {
                                Colors = new[]
                                {
                                    Color.Transparent,
                                    clrJupiterMoonShadowDark,
                                    clrJupiterMoonShadowLight,
                                    clrJupiterMoonShadowLight
                                },
                                Positions = new float[] { 0, f1, f2, 1 }
                            };

                            var regionU = new Region(gpU);
                            regionU.Intersect(gpB);

                            var brushU = new SolidBrush(clrJupiterMoonShadowLight);

                            map.Graphics.FillRegion(brushP, regionP);
                            map.Graphics.FillRegion(brushU, regionU);

                            // outline circles
                            if (settings.Get <bool>("JupiterMoonsShadowOutline") && szP > 20)
                            {
                                map.Graphics.DrawEllipse(penShadowOutline, p.X - (szP + szU) / 4, p.Y - (szP + szU) / 4, (szP + szU) / 2, (szP + szU) / 2);
                                map.Graphics.DrawEllipse(penShadowOutline, p.X - szU / 2, p.Y - szU / 2, szU, szU);

                                PointF[] points = new PointF[] { new PointF(p.X, p.Y) };
                                map.Graphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.World, points);
                                map.Graphics.ResetTransform();
                                map.DrawObjectCaption(fontShadowLabel, brushShadowLabel, moon.ShadowName, points[0], szP);
                            }
                        }
                    }

                    map.Graphics.ResetTransform();
                }
            }
        }
コード例 #30
0
        private void DrawGrid(IMapContext map, Pen penGrid, CelestialGrid grid)
        {
            bool isAnyPoint = false;

            // Azimuths
            for (int j = 0; j < grid.Columns; j++)
            {
                var segments = grid.Column(j)
                               .Select(p => Angle.Separation(grid.ToHorizontal(p, map), map.Center) < map.ViewAngle ? p : null)
                               .Split(p => p == null, true);

                foreach (var segment in segments)
                {
                    for (int k = 0; k < 2; k++)
                    {
                        if (segment.First().RowIndex > 1)
                        {
                            segment.Insert(0, grid[segment.First().RowIndex - 1, j]);
                        }
                    }

                    for (int k = 0; k < 2; k++)
                    {
                        if (segment.Last().RowIndex < grid.Rows - 2)
                        {
                            segment.Add(grid[segment.Last().RowIndex + 1, j]);
                        }
                    }

                    PointF[] refPoints = new PointF[2];
                    for (int k = 0; k < 2; k++)
                    {
                        var coord = grid.FromHorizontal(map.Center, map);
                        coord.Longitude = segment[0].Longitude;
                        coord.Latitude += -map.ViewAngle + k * (map.ViewAngle * 2);
                        coord.Latitude  = Math.Min(coord.Latitude, 80);
                        coord.Latitude  = Math.Max(coord.Latitude, -80);
                        var refHorizontal = grid.ToHorizontal(coord, map);
                        refPoints[k] = map.Project(refHorizontal);
                    }

                    DrawGroupOfPoints(map, penGrid, segment.Select(s => map.Project(grid.ToHorizontal(s, map))).ToArray(), refPoints);

                    isAnyPoint = true;
                }
            }

            // Altitude circles
            for (int i = 0; i < grid.Rows; i++)
            {
                var segments = grid.Row(i)
                               .Select(p => Angle.Separation(grid.ToHorizontal(p, map), map.Center) < map.ViewAngle ? p : null)
                               .Split(p => p == null, true).ToList();

                // segment that starts with point "0 degrees"
                var seg0 = segments.FirstOrDefault(s => s.First().ColumnIndex == 0);

                // segment that ends with point "345 degrees"
                var seg23 = segments.FirstOrDefault(s => s.Last().ColumnIndex == 23);

                // join segments into one
                if (seg0 != null && seg23 != null && seg0 != seg23)
                {
                    segments.Remove(seg0);
                    seg23.AddRange(seg0);
                }

                foreach (var segment in segments)
                {
                    if (segment.Count == 24)
                    {
                        map.Graphics.DrawClosedCurve(penGrid, segment.Select(s => map.Project(grid.ToHorizontal(s, map))).ToArray());
                    }
                    else
                    {
                        for (int k = 0; k < 2; k++)
                        {
                            int col = segment.First().ColumnIndex;
                            if (col == 0)
                            {
                                segment.Insert(0, grid[i, 23]);
                            }
                            else
                            {
                                segment.Insert(0, grid[i, col - 1]);
                            }
                        }

                        for (int k = 0; k < 2; k++)
                        {
                            int col = segment.Last().ColumnIndex;

                            if (col < 23)
                            {
                                segment.Add(grid[i, col + 1]);
                            }
                            else if (col == 23)
                            {
                                segment.Add(grid[i, 0]);
                            }
                        }

                        PointF[] refPoints = new PointF[2];
                        for (int k = 0; k < 2; k++)
                        {
                            var coord = grid.FromHorizontal(map.Center, map);
                            coord.Longitude += -map.ViewAngle + k * (map.ViewAngle * 2);
                            coord.Latitude   = segment[0].Latitude;
                            var refHorizontal = grid.ToHorizontal(coord, map);
                            refPoints[k] = map.Project(refHorizontal);
                        }

                        if (!map.IsOutOfScreen(refPoints[0]) || !map.IsOutOfScreen(refPoints[1]))
                        {
                            refPoints = map.LineScreenIntersection(refPoints[0], refPoints[1]);
                        }

                        DrawGroupOfPoints(map, penGrid, segment.Select(s => map.Project(grid.ToHorizontal(s, map))).ToArray(), refPoints);
                    }

                    isAnyPoint = true;
                }
            }

            // Special case: there are no points visible
            // on the screen at the current position and zoom.
            // Then we select one point that is closest to screen senter.
            if (!isAnyPoint)
            {
                GridPoint closestPoint = grid.Points.OrderBy(p => Angle.Separation(grid.ToHorizontal(p, map), map.Center)).First();
                {
                    var segment = new List <GridPoint>();
                    segment.Add(closestPoint);
                    int i = closestPoint.RowIndex;

                    for (int k = 0; k < 2; k++)
                    {
                        int col = segment.First().ColumnIndex;
                        if (col == 0)
                        {
                            segment.Insert(0, grid[i, 23]);
                        }
                        else
                        {
                            segment.Insert(0, grid[i, col - 1]);
                        }
                    }

                    for (int k = 0; k < 2; k++)
                    {
                        int col = segment.Last().ColumnIndex;

                        if (col < 23)
                        {
                            segment.Add(grid[i, col + 1]);
                        }
                        else if (col == 23)
                        {
                            segment.Add(grid[i, 0]);
                        }
                    }

                    PointF[] refPoints = new PointF[2];
                    for (int k = 0; k < 2; k++)
                    {
                        var coord = grid.FromHorizontal(map.Center, map);
                        coord.Longitude += -map.ViewAngle + k * (map.ViewAngle * 2);
                        coord.Latitude   = segment[0].Latitude;
                        var refHorizontal = grid.ToHorizontal(coord, map);
                        refPoints[k] = map.Project(refHorizontal);
                    }

                    if (!map.IsOutOfScreen(refPoints[0]) || !map.IsOutOfScreen(refPoints[1]))
                    {
                        refPoints = map.LineScreenIntersection(refPoints[0], refPoints[1]);
                    }

                    DrawGroupOfPoints(map, penGrid, segment.Select(s => map.Project(grid.ToHorizontal(s, map))).ToArray(), refPoints);
                }

                {
                    var segment = new List <GridPoint>();
                    segment.Add(closestPoint);
                    int j = closestPoint.ColumnIndex;

                    for (int k = 0; k < 2; k++)
                    {
                        if (segment.First().RowIndex > 1)
                        {
                            segment.Insert(0, grid[segment.First().RowIndex - 1, j]);
                        }
                    }

                    for (int k = 0; k < 2; k++)
                    {
                        if (segment.Last().RowIndex < grid.Rows - 2)
                        {
                            segment.Add(grid[segment.Last().RowIndex + 1, j]);
                        }
                    }

                    PointF[] refPoints = new PointF[2];
                    for (int k = 0; k < 2; k++)
                    {
                        var coord = grid.FromHorizontal(map.Center, map);
                        coord.Longitude = segment[0].Longitude;
                        coord.Latitude += -map.ViewAngle + k * (map.ViewAngle * 2);
                        coord.Latitude  = Math.Min(coord.Latitude, 80);
                        coord.Latitude  = Math.Max(coord.Latitude, -80);
                        var refHorizontal = grid.ToHorizontal(coord, map);
                        refPoints[k] = map.Project(refHorizontal);
                    }

                    DrawGroupOfPoints(map, penGrid, segment.Select(s => map.Project(grid.ToHorizontal(s, map))).ToArray(), refPoints);
                }
            }
        }