private void DrawPlanetGlobe(IMapContext map, Planet planet, float diam) { Graphics g = map.Graphics; float diamEquat = diam; float diamPolar = (1 - planet.Flattening) * diam; bool useTextures = settings.Get <bool>("UseTextures"); if (!(useTextures && (map.Schema == ColorSchema.Red || map.Schema == ColorSchema.White))) { g.FillEllipse(GetPlanetColor(map, planet.Number), -diamEquat / 2, -diamPolar / 2, diamEquat, diamPolar); } if (useTextures) { double grs = planet.Number == Planet.JUPITER ? planetsCalc.GreatRedSpotLongitude : 0; Image texturePlanet = imagesCache.RequestImage(planet.Number.ToString(), new PlanetTextureToken(planet.Number.ToString(), planet.Appearance.CM - grs, planet.Appearance.D), PlanetTextureProvider, map.Redraw); if (texturePlanet != null) { map.DrawImage(texturePlanet, -diamEquat / 2, -diamPolar / 2, diamEquat, diamPolar); DrawVolume(map, diam, planet.Flattening); } } }
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); } } } }
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); } }
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); } }
public static void DrawImage(this IMapContext map, Image image, float x, float y, float width, float height) { map.DrawImage(image, new RectangleF(x, y, width, height), new Rectangle(0, 0, image.Width, image.Height)); }