I would like to draw a circle representing the moon, and over this circle draw an arc representing the sun's illumination for each percentage of illumination. Although the image of this moon is in 2D I need the arc to have a "realism" in its curvature. I would like a function that receives a parameter as a percentage of illumination (eg: 27%) and returns the drawing of the arc with the correct curvature.
CodePudding user response:
Moon terminator is an elliptical arc with vertical axis being constant (equals to Moon diameter) while horizontal axis changes linear with Moon phase
which is
0 - New Moon
0.25 - First Quarter
0.50 - Full Moon
0.75 - Last Quarter
Bitmap creation to show the idea:
private static Bitmap DrawMoon(int radius, float phase) {
phase = (phase % 1 1) % 1;
Bitmap image = new Bitmap(2 * radius, 2 * radius);
var rect = new Rectangle(10, 10, 2 * radius - 20, 2 * radius - 20);
float w = Math.Abs(rect.Width - rect.Width * (4 * phase % 2));
// Terminator is elliptical, verical axis is constant
// While horizontal change as linear function from phase
var term = new RectangleF(
rect.Left (rect.Width - w) / 2, rect.Top, w, rect.Height);
// Width == 10 to exagerate the lines, to show they are elliptical
using var pen = new Pen(Brushes.Yellow, 10);
using (Graphics gs = Graphics.FromImage(image)) {
gs.FillRectangle(Brushes.Black, new Rectangle(0, 0, image.Width, image.Height));
if (phase > 0.5f)
gs.DrawArc(pen, rect, 90, 180);
else
gs.DrawArc(pen, rect, -90, 180);
if (phase < 0.25f || phase > 0.5 && phase < 0.75)
gs.DrawArc(pen, term, -90, 180);
else
gs.DrawArc(pen, term, 90, 180);
}
return image;
}
Several Moon phases (0.12, 0.27, 0.54, 0.95):
If you insist on per cent of illumination you should solve an equation. Moon illumination is an area of the half of the Moon plus or minus half of the ellipse, for instance for phases [0..0.25]
illumination = pi * R * R / 2 - pi * R * R * (0.5 - 2 * phase)
so for the New Moon we have illumination == 0
and for the 1st Quarter illumination == pi * R * R / 2