Click here to Skip to main content
Licence CPOL
First Posted 8 Aug 2010
Views 27,680
Downloads 505
Bookmarked 26 times

Calculate and Draw Moon Phase

By Mostafa Kaisoun | 12 Aug 2010
Calculate Moon's age and draw Moon Phase on any given day

1
1 vote, 5.0%
2
1 vote, 5.0%
3
5 votes, 25.0%
4
13 votes, 65.0%
5
4.70/5 - 20 votes
2 removed
μ 4.52, σa 1.47 [?]

Introduction

Many communities pay close attention to the lunar calendar next to the solar calendar, so I looked at many sites on the internet to know how to calculate the age of the moon on any given day. I found many sites offering different ways, I took what I found to give results closer to the truth.

I've noticed that most sites agree on the expense of the Julian date but do not agree to calculate the age of the moon, and found the difference between these sites up to one day, and when the moon's age is 30 days, the result is zero in some sites.

In this program, I calculated the approximate age of the moon in days and did not give attention to the parts of the day of the hours and minutes.

In order for the program would be more useful, I add PictureBox control to display the lighted part of the moon and darkness part of the moon commensurate with the age of the moon.

img039.JPG

Background

I created two projects, I wrote code of one in C# (2003) and wrote another in VB.NET (2003).

The MoonPhase project has one form (frmMoon) with the following controls:

  • MonthCalendar control (MyCalendar)
  • Button control (btnToDay)
  • Button control (btnClose)
  • PictureBox control (PicMoon)
  • Label control (lblAge)

About the Code

Convert date to Julian date:

private int JulianDate(int d, int m, int y)
{ 
    int mm, yy;
    int k1, k2, k3;
    int j;

    yy = y - (int)((12 - m) / 10);
    mm = m + 9;
    if (mm >= 12)
    {
        mm = mm - 12;
    }
    k1 = (int)(365.25 * (yy + 4712));
    k2 = (int)(30.6001 * mm + 0.5);
    k3 = (int)((int)((yy / 100) + 49) * 0.75) - 38;
    // 'j' for dates in Julian calendar:
    j = k1 + k2 + d + 59;
    if (j > 2299160)
    {
        // For Gregorian calendar:
        j = j - k3; // 'j' is the Julian date at 12h UT (Universal Time)
    }
    return j;
}

Calculate the approximate moon's age in days:

private double MoonAge(int d, int m, int y)
{ 
    int j = JulianDate(d, m, y);
    //Calculate the approximate phase of the moon
    ip = (j + 4.867) / 29.53059;
    ip = ip - Math.Floor(ip); 
    //After several trials I've seen to add the following lines, 
    //which gave the result was not bad 
    if(ip < 0.5)
        ag = ip * 29.53059 + 29.53059 / 2;
    else
        ag = ip * 29.53059 - 29.53059 / 2;
    // Moon's age in days
    ag = Math.Floor(ag) + 1;
    return ag;
}

Draw moon:

private void DrawMoon()
{
    int Xpos, Ypos, Rpos;
    int Xpos1, Xpos2;
    double Phase;

    Phase = ip;
    // Width of 'ImageToDraw' Object = Width of 'PicMoon' control    
    int PageWidth = PicMoon.Width; 
    // Height of 'ImageToDraw' Object = Height of 'PicMoon' control    
    int PageHeight = PicMoon.Height; 
    // Initiate 'ImageToDraw' Object with size = size of control 'PicMoon' control    
    Bitmap ImageToDraw = new Bitmap(PageWidth, PageHeight); 
    // Create graphics object for alteration.    
    Graphics newGraphics = Graphics.FromImage(ImageToDraw);

    Pen PenB = new Pen(Color.Black); // For darkness part of the moon
    Pen PenW = new Pen(Color.White); // For the lighted part of the moon

    for (Ypos=0; Ypos<= 45; Ypos++)
    {
        Xpos = (int)(Math.Sqrt(45*45 - Ypos*Ypos));
        // Draw darkness part of the moon        
        Point pB1 = new Point(90-Xpos, Ypos+90);
        Point pB2 = new Point(Xpos+90, Ypos+90);
        Point pB3 = new Point(90-Xpos, 90-Ypos);
        Point pB4 = new Point(Xpos+90, 90-Ypos);
        newGraphics.DrawLine(PenB, pB1, pB2); 
        newGraphics.DrawLine(PenB, pB3, pB4);        
       // Determine the edges of the lighted part of the moon       
       Rpos = 2 * Xpos;
       if (Phase < 0.5)
       {
           Xpos1 = - Xpos;
           Xpos2 = (int)(Rpos - 2*Phase*Rpos - Xpos);
       }
       else
       {
          Xpos1 = Xpos;
          Xpos2 = (int)(Xpos - 2*Phase*Rpos + Rpos);
       }       
       // Draw the lighted part of the moon       
       Point pW1 = new Point(Xpos1+90, 90-Ypos);
       Point pW2 = new Point(Xpos2+90, 90-Ypos);
       Point pW3 = new Point(Xpos1+90, Ypos+90);
       Point pW4 = new Point(Xpos2+90, Ypos+90);
       newGraphics.DrawLine(PenW, pW1, pW2);
       newGraphics.DrawLine(PenW, pW3, pW4);
    }    
    // Display the bitmap in the picture box.    
    PicMoon.Image = ImageToDraw;    
    // Release graphics object    
    PenB.Dispose();
    PenW.Dispose();
    newGraphics.Dispose();
    ImageToDraw = null;
} 

You can go back to the source file to read the VB.NET code after you extract Moon_VB.zip file.

Final Words

If you have any idea or find another code to calculate the age of the moon, please tell me. Thanks to Code Project and thanks to all.

Mostafa Kaisoun
m_kaisoun@hotmail.com

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Mostafa Kaisoun



Egypt Egypt

Member


Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionError, and another algorithm PinmemberRobert Baker II6:50 7 Sep '11  
AnswerRe: Error, and another algorithm PinmemberRobert Baker II6:55 7 Sep '11  
AnswerRe: Error, and another algorithm PinmemberMostafa Kaisoun10:03 7 Sep '11  
GeneralDraw Moon Phase Under VB6 PinmemberAit amrane14:54 15 Jun '11  
GeneralDraw Moon Phase PinmemberMember 799874711:02 12 Jun '11  
GeneralRe: Draw Moon Phase PinmemberMostafa Kaisoun15:24 13 Jun '11  
GeneralMy vote of 5 Pinmemberdim1315:38 23 Dec '10  
GeneralMy vote of 5 PinmemberPaul Conrad14:50 15 Sep '10  
GeneralGood job - Thanks for sharing... PinmemberSteve Hageman20:11 16 Aug '10  
GeneralRe: Good job - Thanks for sharing... PinmemberMostafa Kaisoun9:34 17 Aug '10  
GeneralGood article Pinmemberdwilliss16:50 10 Aug '10  
GeneralRe: Good article PinmemberMostafa Kaisoun4:58 11 Aug '10  
GeneralMy vote of 5 Pinmembermyker5:53 10 Aug '10  
GeneralRe: My vote of 5 PinmemberMostafa Kaisoun4:55 11 Aug '10  
GeneralDownload MoonPhase C# code PinmemberMostafa Kaisoun7:43 9 Aug '10  
Generalnot Bad, Keep going Mostafa... PinmemberOmar Amin Ibrahim5:11 9 Aug '10  
GeneralRe: not Bad, Keep going Mostafa... PinmemberMostafa Kaisoun5:48 9 Aug '10  
Generalcode not available PinmemberChrist Kennedy12:33 8 Aug '10  
GeneralRe: code not available PinmemberMostafa Kaisoun16:33 8 Aug '10  
GeneralRe: code not available PinmemberChrist Kennedy17:24 8 Aug '10  
GeneralRe: code not available Pinmembervladkoj3:13 9 Aug '10  
GeneralRe: code not available PinmemberMostafa Kaisoun4:03 9 Aug '10  
GeneralRe: code not available PinmemberChrist Kennedy4:49 9 Aug '10  
GeneralRe: code not available PinmemberMostafa Kaisoun5:43 9 Aug '10  
GeneralRe: code not available PinmemberChrist Kennedy6:19 9 Aug '10  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120209.1 | Last Updated 12 Aug 2010
Article Copyright 2010 by Mostafa Kaisoun
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid