public override void Render(IMapContext map) { if (!settings.Get <bool>("DeepSky")) { return; } var allDeepSkies = deepSkyCalc.DeepSkies; bool isGround = settings.Get <bool>("Ground"); brushCaption = new SolidBrush(map.GetColor("ColorDeepSkyLabel")); int alpha = Math.Max(0, Math.Min((int)(k * map.ViewAngle + b), 255)); Color colorOutline = map.GetColor("ColorDeepSkyOutline"); penOutlineSolid = new Pen(Color.FromArgb(alpha, colorOutline)); penOutlineDashed = new Pen(Color.FromArgb(alpha, colorOutline)); penOutlineDashed.DashStyle = DashStyle.Dash; var deepSkies = allDeepSkies.Where(ds => !ds.Status.IsEmpty() && Angle.Separation(map.Center, ds.Horizontal) < map.ViewAngle); if (isGround) { deepSkies = deepSkies.Where(ds => ds.Horizontal.Altitude + ds.Semidiameter / 3600 > 0); } foreach (var ds in deepSkies) { drawingHandlers[ds.Status].Draw(map, settings, ds); } }
public override void Render(IMapContext map) { brushLabel = new SolidBrush(map.GetColor("ColorSolarSystemLabel")); var bodies = planetsCalc.Planets .Where(p => p.Number != Planet.EARTH) .Cast <SolarSystemObject>() .Concat(new[] { sun }) .OrderByDescending(body => body.Ecliptical.Distance) .ToArray(); foreach (var body in bodies) { if (body is Planet planet) { RenderPlanet(map, planet); } else { RenderSun(map); } } RenderMoon(map); if (map.Schema == ColorSchema.Day) { DrawHalo(map); } RenderEarthShadow(map); }
/// <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]); } } } } }
/// <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); } } }
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); } } } } }
public override void Render(IMapContext map) { peFrom1950 = Precession.ElementsFK5(Date.EPOCH_B1950, map.JulianDay); peTo1950 = Precession.ElementsFK5(map.JulianDay, Date.EPOCH_B1950); Color colorGridEquatorial = map.GetColor("ColorEquatorialGrid"); Color colorGridHorizontal = map.GetColor("ColorHorizontalGrid"); Color colorLineEcliptic = map.GetColor("ColorEcliptic"); Color colorLineGalactic = map.GetColor("ColorGalacticEquator"); Color colorLineMeridian = map.GetColor("ColorMeridian"); penGridEquatorial.Color = colorGridEquatorial; penGridHorizontal.Color = colorGridHorizontal; penLineEcliptic.Color = colorLineEcliptic; penLineGalactic.Color = colorLineGalactic; penLineMeridian.Color = colorLineMeridian; if (settings.Get <bool>("GalacticEquator")) { DrawGrid(map, penLineGalactic, LineGalactic); } if (settings.Get <bool>("EquatorialGrid")) { DrawGrid(map, penGridEquatorial, GridEquatorial); DrawEquatorialPoles(map); } if (settings.Get <bool>("HorizontalGrid")) { DrawGrid(map, penGridHorizontal, GridHorizontal); DrawHorizontalPoles(map); } if (settings.Get <bool>("EclipticLine")) { DrawGrid(map, penLineEcliptic, LineEcliptic); DrawEquinoxLabels(map); DrawLunarNodes(map); } if (settings.Get <bool>("MeridianLine")) { DrawGrid(map, penLineMeridian, LineMeridian); } }
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}"); } } }
private Color GetColor(IMapContext map, char spClass) { if (map.Schema == ColorSchema.White) { return(Color.Black); } if (settings.Get("StarsColors")) { switch (spClass) { case 'O': case 'W': starColor = Color.LightBlue; break; case 'B': starColor = Color.LightCyan; break; case 'A': starColor = Color.White; break; case 'F': starColor = Color.LightYellow; break; case 'G': starColor = Color.Yellow; break; case 'K': starColor = Color.Orange; break; case 'M': starColor = Color.OrangeRed; break; default: starColor = Color.White; break; } } else { starColor = Color.White; } return(map.GetColor(starColor, Color.Transparent)); }
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); } } } } }
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); } } } }
/// <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); } } }
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; } } }
private Brush GetPlanetColor(IMapContext map, int planet) { Color color = Color.Empty; switch (planet) { case 1: color = Color.FromArgb(132, 131, 131); break; case 2: color = Color.FromArgb(228, 189, 127); break; case 4: color = Color.FromArgb(183, 98, 71); break; case 5: color = Color.FromArgb(166, 160, 149); break; case 6: color = Color.FromArgb(207, 192, 162); break; case 7: color = Color.FromArgb(155, 202, 209); break; case 8: color = Color.FromArgb(54, 79, 167); break; default: color = Color.White; break; } return(new SolidBrush(map.GetColor(color))); }
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); } } } }
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); } } } } } }
public override void Render(IMapContext map) { Graphics g = map.Graphics; var allAsteroids = asteroidsCalc.Asteroids; bool isGround = settings.Get <bool>("Ground"); bool drawAsteroids = settings.Get <bool>("Asteroids"); bool drawLabels = settings.Get <bool>("AsteroidsLabels"); bool drawAll = settings.Get <bool>("AsteroidsDrawAll"); decimal drawAllMagLimit = settings.Get <decimal>("AsteroidsDrawAllMagLimit"); bool drawLabelMag = settings.Get <bool>("AsteroidsLabelsMag"); Brush brushNames = new SolidBrush(map.GetColor("ColorAsteroidsLabels")); var font = settings.Get <Font>("AsteroidsLabelsFont"); if (drawAsteroids) { var asteroids = allAsteroids.Where(a => Angle.Separation(map.Center, a.Horizontal) < map.ViewAngle); foreach (var a in asteroids) { double ad = Angle.Separation(a.Horizontal, map.Center); if ((!isGround || a.Horizontal.Altitude + a.Semidiameter / 3600 > 0) && ad < map.ViewAngle + a.Semidiameter / 3600) { float diam = map.GetDiskSize(a.Semidiameter); float size = map.GetPointSize(a.Magnitude); // if "draw all" setting is enabled, draw asteroids brighter than limit if (drawAll && size < 1 && a.Magnitude <= (float)drawAllMagLimit) { size = 1; } string label = drawLabelMag ? $"{a.Name} {Formatters.Magnitude.Format(a.Magnitude)}" : a.Name; // asteroid should be rendered as disk if ((int)diam > 0 && diam > size) { PointF p = map.Project(a.Horizontal); map.Graphics.FillEllipse(new SolidBrush(map.GetColor(colorAsteroid)), p.X - diam / 2, p.Y - diam / 2, diam, diam); DrawVolume(map, diam, 0); if (drawLabels) { map.DrawObjectCaption(font, brushNames, label, p, diam); } map.AddDrawnObject(a); continue; } // asteroid should be rendered as point else if ((int)size > 0) { PointF p = map.Project(a.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(a); continue; } } } } } }
public override void Render(IMapContext map) { Graphics g = map.Graphics; var allAsteroids = asteroidsCalc.Asteroids; bool isGround = settings.Get <bool>("Ground"); double coeff = map.DiagonalCoefficient(); bool drawAsteroids = settings.Get <bool>("Asteroids"); bool drawLabels = settings.Get <bool>("AsteroidsLabels"); Brush brushNames = new SolidBrush(map.GetColor("ColorAsteroidsLabels")); if (drawAsteroids) { var asteroids = allAsteroids.Where(a => Angle.Separation(map.Center, a.Horizontal) < map.ViewAngle * coeff); foreach (var a in asteroids) { double ad = Angle.Separation(a.Horizontal, map.Center); if ((!isGround || a.Horizontal.Altitude + a.Semidiameter / 3600 > 0) && ad < coeff * map.ViewAngle + a.Semidiameter / 3600) { float diam = map.GetDiskSize(a.Semidiameter); // asteroid should be rendered as disk if ((int)diam > 0) { PointF p = map.Project(a.Horizontal); map.Graphics.FillEllipse(new SolidBrush(map.GetColor(colorAsteroid)), p.X - diam / 2, p.Y - diam / 2, diam, diam); DrawVolume(map, diam, 0); if (drawLabels) { map.DrawObjectCaption(fontNames, brushNames, a.Name, p, diam); } map.AddDrawnObject(a); continue; } // asteroid should be rendered as point float size = map.GetPointSize(a.Magnitude, maxDrawingSize: 3); if ((int)size > 0) { PointF p = map.Project(a.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(fontNames, brushNames, a.Name, p, size); } map.AddDrawnObject(a); continue; } } } } } }
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); } } } } }
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; } } } } }
public override void Render(IMapContext map) { 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.Any(h => !map.IsOutOfScreen(h))) { GraphicsPath gp = new GraphicsPath(); gp.AddCurve(hor); var pts = map.IsInverted ? new PointF[] { new PointF(map.Width + 1, -1), new PointF(-1, -1), } : new PointF[] { new PointF(map.Width + 1, map.Height + 1), new PointF(-1, map.Height + 1) }; if (hor.Last().X > map.Width / 2) { gp.AddLines(pts); } else { gp.AddLines(pts.Reverse().ToArray()); } 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.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.Near, 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) { PointF p = map.Project(h); var fontBase = settings.Get <Font>("CardinalDirectionsFont"); var font = new Font(fontBase.FontFamily, fontBase.Size * (i % 2 == 0 ? 1 : 0.75f), fontBase.Style); using (var gp = new GraphicsPath()) { map.Graphics.DrawString(Text.Get($"CardinalDirections.{cardinalDirections[i]}"), font, brushCardinalLabels, p, format); } } } } }
public override void Render(IMapContext map) { Graphics g = map.Graphics; var allStars = starsCalc.Stars; bool isGround = settings.Get <bool>("Ground"); if (settings.Get <bool>("ConstLines")) { PointF p1, p2; CrdsHorizontal h1, h2; penConLine.Brush = new SolidBrush(map.GetColor("ColorConstLines")); foreach (var line in sky.ConstellationLines) { h1 = allStars.ElementAt(line.Item1).Horizontal; h2 = allStars.ElementAt(line.Item2).Horizontal; if ((!isGround || h1.Altitude > 0 || h2.Altitude > 0) && Angle.Separation(map.Center, h1) < 90 && Angle.Separation(map.Center, h2) < 90) { p1 = map.Project(h1); p2 = map.Project(h2); var points = map.SegmentScreenIntersection(p1, p2); if (points.Length == 2) { g.DrawLine(penConLine, points[0], points[1]); } } } } if (settings.Get <bool>("Stars") && !(map.Schema == ColorSchema.Day && map.DayLightFactor == 1)) { var stars = allStars.Where(s => s != null && Angle.Separation(map.Center, s.Horizontal) < map.ViewAngle); if (isGround) { stars = stars.Where(s => s.Horizontal.Altitude >= 0); } foreach (var star in stars) { 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(new SolidBrush(GetColor(map, star.Color)), p.X - diam / 2, p.Y - diam / 2, diam, diam); map.AddDrawnObject(star); } } } if (settings.Get <bool>("StarsLabels") && map.ViewAngle <= limitAllNames) { brushStarNames = new SolidBrush(map.GetColor("ColorStarsLabels")); foreach (var star in stars) { float diam = map.GetPointSize(star.Mag); if ((int)diam > 0) { PointF p = map.Project(star.Horizontal); if (!map.IsOutOfScreen(p)) { DrawStarName(map, p, star, diam); } } } } } }
private void RenderSun(IMapContext map) { if (!settings.Get <bool>("Sun")) { return; } bool isGround = settings.Get <bool>("Ground"); bool useTextures = settings.Get <bool>("SunTexture"); double ad = Angle.Separation(sun.Horizontal, map.Center); double coeff = map.DiagonalCoefficient(); Color colorSun = map.GetColor(clrSunNight, clrSunDaylight); if ((!isGround || sun.Horizontal.Altitude + sun.Semidiameter / 3600 > 0) && ad < coeff * map.ViewAngle + sun.Semidiameter / 3600) { PointF p = map.Project(sun.Horizontal); float inc = map.GetRotationTowardsNorth(sun.Equatorial); map.Graphics.TranslateTransform(p.X, p.Y); map.Graphics.RotateTransform(inc); float size = map.GetDiskSize(sun.Semidiameter, 10); if (map.Schema == ColorSchema.Night && useTextures && size > 10) { Date date = new Date(map.JulianDay); DateTime dt = new DateTime(date.Year, date.Month, (int)date.Day, 0, 0, 0, DateTimeKind.Utc); Brush brushSun = new SolidBrush(clrSunNight); Image imageSun = imagesCache.RequestImage("Sun", dt, SunImageProvider, map.Redraw); map.Graphics.FillEllipse(brushSun, -size / 2, -size / 2, size, size); if (imageSun != null) { map.Graphics.DrawImage(imageSun, -size / 2, -size / 2, size, size); } } else { if (map.Schema == ColorSchema.White) { map.Graphics.FillEllipse(Brushes.White, -size / 2, -size / 2, size, size); map.Graphics.DrawEllipse(Pens.Black, -size / 2, -size / 2, size, size); } else { Brush brushSun = new SolidBrush(colorSun); map.Graphics.FillEllipse(brushSun, -size / 2, -size / 2, size, size); } } map.Graphics.ResetTransform(); if (settings.Get <bool>("SunLabel")) { map.DrawObjectCaption(fontLabel, brushLabel, sun.Name, p, size); } map.AddDrawnObject(sun); } }
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); } } } } }
private void RenderMoon(IMapContext map) { if (!settings.Get <bool>("Moon")) { return; } bool isGround = settings.Get <bool>("Ground"); bool useTextures = settings.Get <bool>("MoonTexture"); double ad = Angle.Separation(moon.Horizontal, map.Center); double coeff = map.DiagonalCoefficient(); if ((!isGround || moon.Horizontal.Altitude + moon.Semidiameter / 3600 > 0) && ad < coeff * map.ViewAngle + moon.Semidiameter / 3600.0) { PointF p = map.Project(moon.Horizontal); double inc = map.GetRotationTowardsNorth(moon.Equatorial); // final rotation of drawn image // axis rotation is negated because measured counter-clockwise float axisRotation = (float)(inc - moon.PAaxis); map.Graphics.TranslateTransform(p.X, p.Y); map.Graphics.RotateTransform(axisRotation); // drawing size float size = map.GetDiskSize(moon.Semidiameter, 10); SolidBrush brushMoon = new SolidBrush(map.GetColor(Color.Gray)); if (useTextures && size > 10) { Image textureMoon = imagesCache.RequestImage("Moon", new PlanetTextureToken("Moon", moon.Libration.l, moon.Libration.b), MoonTextureProvider, map.Redraw); if (textureMoon != null) { map.Graphics.FillEllipse(brushMoon, -size / 2, -size / 2, size, size); map.DrawImage(textureMoon, -size / 2, -size / 2, size, size); } else { map.Graphics.FillEllipse(brushMoon, -size / 2, -size / 2, size, size); } } else { // Moon disk map.Graphics.FillEllipse(brushMoon, -size / 2, -size / 2, size, size); } map.Graphics.ResetTransform(); float phase = (float)moon.Phase * Math.Sign(moon.Elongation); float rotation = map.GetRotationTowardsEclipticPole(moon.Ecliptical0); GraphicsPath shadow = GetPhaseShadow(phase, size + 1); // shadowed part of disk map.Graphics.TranslateTransform(p.X, p.Y); map.Graphics.RotateTransform(rotation); map.Graphics.FillPath(GetShadowBrush(map), shadow); map.Graphics.ResetTransform(); if (settings.Get <bool>("MoonLabel")) { map.DrawObjectCaption(fontLabel, brushLabel, moon.Name, p, size); } map.AddDrawnObject(moon); } }