winform 繪制太陽,地球,月球 運作規律
最近我太太在考公學習,給我出了兩道高中地理知識的題目,把我問的一頭霧水,題目是這樣的
第一題

第二題
看到這兩道題,當時大腦飛速運轉,差點整個身體都在自轉了,所以產生了個偷懶的方法,用程序代替冥想,所以就有了這個小玩意的誕生.
Linux 的創始人 Linus Torvalds 在 2000-08-25 給linux-kernel 郵件列表的一封郵件提到的:
能說算不上什么,有本事就把你的代碼給我看看。

1. 創建基本類
首先,我們創建一些基本的類來表示天體(如太陽、地球和月球)以及它們的運動。
public class CelestialBody
{
public string Name { get; set; }
public int Radius { get; set; } // 半徑
public Color Color { get; set; } // 顏色
public double DistanceFromSun { get; set; } // 距離太陽的距離
public double OrbitalPeriod { get; set; } // 軌道周期(天)
public double RotationPeriod { get; set; } // 自轉周期(天)
public double CurrentAngle { get; set; } // 當前角度(弧度)
public CelestialBody(string name, int radius, Color color, double distanceFromSun, double orbitalPeriod, double rotationPeriod)
{
Name = name;
Radius = radius;
Color = color;
DistanceFromSun = distanceFromSun;
OrbitalPeriod = orbitalPeriod;
RotationPeriod = rotationPeriod;
CurrentAngle = 0;
}
public void UpdatePosition(double timeStep)
{
// 計算角速度(弧度/天)
double angularVelocity = 2 * Math.PI / OrbitalPeriod;
// 更新當前角度
CurrentAngle += angularVelocity * timeStep;
// 確保角度在0到2π之間
CurrentAngle %= 2 * Math.PI;
}
public (double X, double Y) GetPosition()
{
// 計算當前天體的位置
double x = DistanceFromSun * Math.Cos(CurrentAngle);
double y = DistanceFromSun * Math.Sin(CurrentAngle);
return (x, y);
}
}
2. 創建太陽、地球和月球
接下來,我們創建太陽、地球和月球的實例,并設置它們的屬性。
// 初始化天體
sun = new CelestialBody("Sun", 50, Color.Yellow, 0, 0, 0); // 太陽靜止不動
earth = new CelestialBody("Earth", 10, Color.Blue, 150, 365.25, 1); // 地球
moon = new CelestialBody("Moon", 5, Color.Gray, 30, 27.32, 27.32); // 月球
并且初始化一個定時器,用于刷新三個球體的運行狀態
private void Timer_Tick(object sender, EventArgs e)
{
// 更新天體的位置
earth.UpdatePosition(0.1); // 時間步長為0.1天
moon.UpdatePosition(0.1);
// 重繪窗體
this.Invalidate();
}
開始繪制太陽,地球和月亮
// 獲取繪圖對象 graphics = e.Graphics; graphics.Clear(Color.Black); // 繪制太陽 DrawCelestialBody(sun, 400, 400); // 繪制地球 var earthPosition = earth.GetPosition(); DrawCelestialBody(earth, 400 + (int)earthPosition.X, 400 + (int)earthPosition.Y); // 繪制月球 var moonPosition = moon.GetPosition(); DrawCelestialBody(moon, 400 + (int)earthPosition.X + (int)moonPosition.X, 400 + (int)earthPosition.Y + (int)moonPosition.Y);
3. 運行模擬
運行上述代碼,你將看到地球和月球的位置變化。這個模擬是一個非常簡化的模型,假設地球和月球的軌道是完美的圓形,并且忽略了其他天體的引力影響。

看上去有點丑,我們添加寫素材,去掉已知的軌跡邊框,并且找些素材美化他們

并且標識出赤道和經線,以及南北半球
// 繪制南北半球標識 graphics.DrawLine(Pens.Red, x - radius, y, x + radius, y); // 赤道 graphics.DrawLine(Pens.Yellow, x, y - radius, x, y + radius); // 經線 // 繪制北極和南極 graphics.FillEllipse(Brushes.White, x - 3, y - radius - 3, 6, 6); // 北極 graphics.FillEllipse(Brushes.Green, x - 3, y + radius - 3, 6, 6); // 南極
如上我們繪制一條紅線標識赤道,黃線標識經線,白色圓點表示北極,綠色圓點表示南極,這樣方便我們根據不同象限,在腦海里面構思具體經緯度
4. 最終效果

加上地球自轉的特效
// 創建一個旋轉矩陣
Matrix transform = new Matrix();
transform.RotateAt((float)(body.CurrentRotationAngle * 180 / Math.PI), new PointF(x, y));
// 應用旋轉矩陣
graphics.Transform = transform;
// 繪制天體紋理
if (body.Name == "Earth")
{
graphics.DrawImage(earthTexture, x - body.Radius, y - body.Radius, body.Radius * 2, body.Radius * 2);
}
else
{
graphics.FillEllipse(new SolidBrush(body.Color), x - body.Radius, y - body.Radius, body.Radius * 2, body.Radius * 2);
}
// 重置變換
graphics.ResetTransform();

圖片素材 https://polyhaven.com/textures
4. 解題思路
四季變化的總結
-
根本原因:地球自轉軸的傾斜(約 23.5 度)。
-
直接原因:地球在公轉過程中,太陽直射點在南北回歸線之間移動。
-
結果:不同時間段,地球表面接收到的太陽輻射量不同,從而導致溫度變化和四季交替。
四季變化的原理
由于地球自轉軸的傾斜,地球在公轉過程中,不同時間段的太陽直射點會發生變化,從而導致四季變化。具體過程如下:
(1)春分和秋分
-
當地球公轉到春分(約 3 月 21 日)和秋分(約 9 月 23 日)時,太陽直射點位于赤道。
-
此時,全球晝夜幾乎等長。
-
北半球和南半球的季節相反(例如,北半球是春季,南半球是秋季)。
(2)夏至
-
當地球公轉到夏至(約 6 月 21 日)時,太陽直射點位于北回歸線(北緯 23.5 度)。
-
此時,北半球白天最長,夜晚最短,進入夏季;南半球則相反,進入冬季。
(3)冬至
-
當地球公轉到冬至(約 12 月 22 日)時,太陽直射點位于南回歸線(南緯 23.5 度)。
-
此時,北半球白天最短,夜晚最長,進入冬季;南半球則相反,進入夏季。
有了如圖展示發現:
第一題,在四大衛星發射中心中,不僅僅文昌衛星發射中心位于低緯度,其他選項ABC都正確,D錯誤。
第二題,A,D兩項都是錯誤的!:春分(3.21前后),秋分(9.23前后)太陽直射在赤道上,驚蟄(3.5)在春分之前,因此這一天太陽直射點仍在南半球,切太陽直射點在向北移動。BC兩項:驚蟄(3.5)在春分前,此時太陽直射點仍在南半球,南半球晝長夜短,北半球晝短夜長,且北極圈內部分地區存在極夜現象,B錯誤,所以選C
5. 結束語
最后,預祝各位考公學子,榜上有名!成功上岸!
感謝各位耐心查閱! 由于系統引用文件較多,壓縮后源碼文件仍然很大,如果有需要源碼的朋友,可以微信公眾號聯系博主,源碼可以免費贈予~!如果覺得本篇博文對您或者身邊朋友有幫助的,麻煩點個關注!贈人玫瑰,手留余香,您的支持就是我寫作最大的動力,感謝您的關注,期待和您一起探討!再會!
作者:Stephen-kzx
出處:http://www.rzrgm.cn/axing/
公眾號:會定時分享寫工作中或者生活中遇到的小游戲和小工具源碼。有興趣的幫忙點下關注!感恩!
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。

浙公網安備 33010602011771號