月球年龄计算与月相显示

在研究日历的时候,通常会关注公历,但很少有人注意到农历。为了计算任何给定日期的月球年龄,浏览了互联网上的许多网站。发现许多网站提供了不同的计算方法,采纳了其中一些方法,以期得到更接近真实情况的结果。

注意到,大多数网站在计算儒略日时意见一致,但在计算月球年龄时却存在分歧,这些网站之间的差异可能高达一天。当月球年龄为30天时,一些网站的结果为零。

在这个程序中,计算了月球的大致年龄(以天为单位),并没有关注小时和分钟的部分。为了让程序更有用,添加了一个PictureBox控件来显示与月球年龄相对应的月球亮面和暗面。

创建了两个项目,一个用C#(2003)编写,另一个用VB.NET(2003)编写。MoonPhase项目有一个表单(frmMoon),包含以下控件:MonthCalendar控件(MyCalendar)、Button控件(btnToDay)、Button控件(btnClose)、PictureBox控件(PicMoon)和Label控件(lblAge)。

代码解析

将日期转换为儒略日:

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)((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; }

计算月球的大致年龄(以天为单位):

private double MoonAge(int d, int m, int y) { int j = JulianDate(d, m, y); // Calculate the approximate phase of the moon double 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) { double ag = ip * 29.53059 + 29.53059 / 2; } else { double ag = ip * 29.53059 - 29.53059 / 2; } // Moon's age in days ag = Math.Floor(ag) + 1; return ag; }

绘制月球:

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; }

如果想查看VB.NET代码,请解压Moon_VB.zip文件后返回源文件。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485