在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#语言基础 → 太阳系行星运行模拟

太阳系行星运行模拟

C#语言基础

下载此实例
  • 开发语言:C#
  • 实例大小:0.24M
  • 下载次数:0
  • 浏览次数:3
  • 发布时间:2025-11-10
  • 实例类别:C#语言基础
  • 发 布 人:terry_tj
  • 文件格式:.rar
  • 所需积分:2
 相关标签: 太阳系行星运行模拟

实例介绍

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Linq;

namespace InnerSolarSystemSimulation
{
    public partial class InnerSolarSystemForm : Form
    {
        private Timer animationTimer;
        private List<CelestialBody> bodies;
        private Bitmap canvas;
        private Graphics graphics;
        private Font labelFont;
        private Font smallFont;

        // 放大缩放因子
        private const float DistanceScale = 150.0f;  // 从80增加到150,放大轨迹
        private const float PlanetSizeScale = 4000.0f; // 增加行星大小
        private const float MoonDistanceScale = 8.0f; // 增加月球轨道显示大小

        public InnerSolarSystemForm()
        {
            InitializeComponent();
            InitializeSolarSystem();
            InitializeCanvas();
            SetupTimer();
        }

        private void InitializeComponent()
        {
            this.Text = "内太阳系模拟 - 含月球轨道 (放大版)";
            this.Size = new Size(1400, 1000); // 增加窗体大小
            this.DoubleBuffered = true;
            this.BackColor = Color.Black;
        }

        private void InitializeSolarSystem()
        {
            bodies = new List<CelestialBody>();

            // 太阳109f
            bodies.Add(new CelestialBody("太阳", 0, 0, 50f, 0, 0, Color.Yellow, true));

            // 行星数据:名称, 半长轴(AU), 公转周期(年), 半径(地球半径), 偏心率, 颜色
            // 水星
            bodies.Add(new CelestialBody("水星", 0.387f, 0.241f, 0.383f, 0.2056f, 0, Color.LightGray));

            // 金星
            bodies.Add(new CelestialBody("金星", 0.723f, 0.615f, 0.949f, 0.0068f, 0, Color.Goldenrod));

            // 地球(包含月球)
            CelestialBody earth = new CelestialBody("地球", 1.000f, 1.000f, 1.000f, 0.0167f, 0, Color.DodgerBlue);
            // 添加月球作为地球的卫星 - 使用更精确的月球数据
            earth.AddMoon(new Moon("月球", 0.02257f, 0.0748f, 0.2727f, 0.0549f, Color.LightGray));
            bodies.Add(earth);

            // 火星
            bodies.Add(new CelestialBody("火星", 1.524f, 1.881f, 0.532f, 0.0934f, 0, Color.OrangeRed));

            labelFont = new Font("Arial", 10, FontStyle.Bold);
            smallFont = new Font("Arial", 8);
        }

        private void InitializeCanvas()
        {
            canvas = new Bitmap(ClientSize.Width, ClientSize.Height);
            graphics = Graphics.FromImage(canvas);
        }

        private void SetupTimer()
        {
            animationTimer = new Timer();
            animationTimer.Interval = 20;
            animationTimer.Tick = (s, e) =>
            {
                UpdatePositions();
                Invalidate();
            };
            animationTimer.Start();
        }

        private void UpdatePositions()
        {
            foreach (var body in bodies)
            {
                if (!body.IsSun)
                {
                    body.UpdatePosition(0.002); // 调整时间步长
                }
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            if (canvas == null || canvas.Width != ClientSize.Width || canvas.Height != ClientSize.Height)
            {
                InitializeCanvas();
            }

            graphics.Clear(Color.Black);
            DrawSolarSystem(graphics);
            e.Graphics.DrawImage(canvas, 0, 0);
        }

        private void DrawSolarSystem(Graphics g)
        {
            int centerX = ClientSize.Width / 2;
            int centerY = ClientSize.Height / 2;

            // 绘制所有轨道
            foreach (var body in bodies)
            {
                if (!body.IsSun)
                {
                    DrawBodyOrbit(g, body, centerX, centerY);
                }
            }

            // 绘制所有天体
            foreach (var body in bodies)
            {
                DrawCelestialBody(g, body, centerX, centerY);
            }

            // 绘制图例
            DrawLegend(g);
        }

        private void DrawBodyOrbit(Graphics g, CelestialBody body, int centerX, int centerY)
        {
            // 绘制行星轨道
            float semiMajorAxis = body.SemiMajorAxis * DistanceScale;
            float semiMinorAxis = semiMajorAxis * (float)Math.Sqrt(1 - body.Eccentricity * body.Eccentricity);
            float focusDistance = semiMajorAxis * body.Eccentricity;

            RectangleF orbitRect = new RectangleF(
                centerX - semiMajorAxis focusDistance,
                centerY - semiMinorAxis,
                semiMajorAxis * 2,
                semiMinorAxis * 2
            );

            using (Pen orbitPen = new Pen(Color.FromArgb(100, body.Color), 1.5f)) // 加粗轨道线
            {
                g.DrawEllipse(orbitPen, orbitRect);
            }

            // 如果天体有卫星,绘制卫星轨道
            if (body.HasMoon)
            {
                PointF bodyPosition = body.GetPosition(centerX, centerY, DistanceScale);
                float moonOrbitRadius = body.Moon.SemiMajorAxis * DistanceScale * MoonDistanceScale;

                // 绘制月球椭圆轨道
                float moonSemiMajorAxis = moonOrbitRadius;
                float moonSemiMinorAxis = moonOrbitRadius * (float)Math.Sqrt(1 - body.Moon.Eccentricity * body.Moon.Eccentricity);
                float moonFocusDistance = moonSemiMajorAxis * body.Moon.Eccentricity;

                RectangleF moonOrbitRect = new RectangleF(
                    bodyPosition.X - moonSemiMajorAxis moonFocusDistance,
                    bodyPosition.Y - moonSemiMinorAxis,
                    moonSemiMajorAxis * 2,
                    moonSemiMinorAxis * 2
                );

                using (Pen moonOrbitPen = new Pen(Color.FromArgb(80, Color.LightBlue), 1f))
                {
                    g.DrawEllipse(moonOrbitPen, moonOrbitRect);
                }
            }
        }

        private void DrawCelestialBody(Graphics g, CelestialBody body, int centerX, int centerY)
        {
            if (body.IsSun)
            {
                // 绘制太阳
                float sunSize = Math.Max(30, body.Radius * PlanetSizeScale / 3000f);
                g.FillEllipse(Brushes.Yellow, centerX - sunSize / 2, centerY - sunSize / 2, sunSize, sunSize);
                g.DrawString(body.Name, labelFont, Brushes.White, centerX - 15, centerY sunSize / 2 5);
                return;
            }

            // 绘制行星
            PointF position = body.GetPosition(centerX, centerY, DistanceScale);
            float size = Math.Max(5, body.Radius * PlanetSizeScale / 100f);
            size = Math.Min(size, 35); // 增加最大尺寸

            // 绘制行星(带光晕效果)
            g.FillEllipse(new SolidBrush(body.Color), position.X - size / 2, position.Y - size / 2, size, size);
            g.DrawEllipse(new Pen(Color.White, 1), position.X - size / 2, position.Y - size / 2, size, size);

            // 绘制行星名称
            g.DrawString(body.Name, labelFont, Brushes.White, position.X size 2, position.Y - 8);

            // 绘制轨迹
            DrawBodyTrail(g, body, centerX, centerY);

            // 绘制卫星(如果有)
            if (body.HasMoon)
            {
                DrawMoon(g, body, position);
            }
        }

        private void DrawMoon(Graphics g, CelestialBody planet, PointF planetPosition)
        {
            PointF moonPosition = planet.Moon.GetPositionRelativeToPlanet(planetPosition, MoonDistanceScale * DistanceScale);
            float moonSize = Math.Max(3, planet.Moon.Radius * PlanetSizeScale / 100f);

            // 绘制月球
            g.FillEllipse(new SolidBrush(planet.Moon.Color),
                         moonPosition.X - moonSize / 2,
                         moonPosition.Y - moonSize / 2,
                         moonSize,
                         moonSize);

            // 在月球旁边显示名称
            if (planet.Name == "地球")
            {
                g.DrawString(planet.Moon.Name, smallFont, Brushes.White, moonPosition.X moonSize 2, moonPosition.Y - 6);
            }

            // 绘制月球轨迹
            DrawMoonTrail(g, planet, planetPosition);
        }

        private void DrawBodyTrail(Graphics g, CelestialBody body, int centerX, int centerY)
        {
            if (body.PositionHistory.Count < 2) return;

            using (Pen trailPen = new Pen(Color.FromArgb(120, body.Color), 1.5f))
            {
                for (int i = 0; i < body.PositionHistory.Count - 1; i )
                {
                    PointF p1 = body.PositionHistory[i];
                    PointF p2 = body.PositionHistory[i 1];
                    g.DrawLine(trailPen, p1, p2);
                }
            }
        }

        private void DrawMoonTrail(Graphics g, CelestialBody planet, PointF planetPosition)
        {
            if (planet.Moon.PositionHistory.Count < 2) return;

            using (Pen trailPen = new Pen(Color.FromArgb(100, Color.Cyan), 1f))
            {
                for (int i = 0; i < planet.Moon.PositionHistory.Count - 1; i )
                {
                    PointF p1 = planet.Moon.PositionHistory[i];
                    PointF p2 = planet.Moon.PositionHistory[i 1];
                    g.DrawLine(trailPen, p1, p2);
                }
            }
        }

        private void DrawLegend(Graphics g)
        {
            int startX = 20;
            int startY = 20;

            g.DrawString("内太阳系模拟 - 放大版",
                        new Font("Arial", 16, FontStyle.Bold),
                        Brushes.White, startX, startY);

            g.DrawString("太阳 水星 金星 地球 月球 火星",
                        new Font("Arial", 10), Brushes.LightGray, startX, startY 30);

            // 显示数据表格
            DrawDataTable(g, startX, startY 70);

            // 显示月球轨道说明
            DrawMoonInfo(g, startX 400, startY 70);
        }

        private void DrawDataTable(Graphics g, int startX, int startY)
        {
            g.DrawString("天体轨道数据:", new Font("Arial", 11, FontStyle.Bold),
                        Brushes.White, startX, startY);

            // 表头
            g.DrawString("天体", new Font("Arial", 9, FontStyle.Bold), Brushes.Yellow, startX, startY 25);
            g.DrawString("轨道半径(AU)", new Font("Arial", 9, FontStyle.Bold), Brushes.Yellow, startX 80, startY 25);
            g.DrawString("偏心率", new Font("Arial", 9, FontStyle.Bold), Brushes.Yellow, startX 180, startY 25);
            g.DrawString("公转周期", new Font("Arial", 9, FontStyle.Bold), Brushes.Yellow, startX 250, startY 25);

            int row = 0;
            foreach (var body in bodies)
            {
                if (body.IsSun) continue;

                int rowY = startY 45 (row * 20);

                g.DrawString(body.Name, labelFont, new SolidBrush(body.Color), startX, rowY);
                g.DrawString($"{body.SemiMajorAxis:F3}", labelFont, Brushes.White, startX 80, rowY);
                g.DrawString(body.Eccentricity.ToString("F4"), labelFont, Brushes.White, startX 180, rowY);
                g.DrawString($"{body.OrbitalPeriod:F3} 年", labelFont, Brushes.White, startX 250, rowY);

                row ;

                // 显示月球数据
                if (body.HasMoon)
                {
                    int moonRowY = startY 45 (row * 20);
                    g.DrawString("↳ " body.Moon.Name, smallFont, new SolidBrush(body.Moon.Color), startX 20, moonRowY);
                    g.DrawString($"{body.Moon.SemiMajorAxis:F5}", smallFont, Brushes.LightGray, startX 80, moonRowY);
                    g.DrawString(body.Moon.Eccentricity.ToString("F4"), smallFont, Brushes.LightGray, startX 180, moonRowY);
                    g.DrawString($"{body.Moon.OrbitalPeriod:F3} 年", smallFont, Brushes.LightGray, startX 250, moonRowY);
                    g.DrawString($"(约{Math.Round(body.Moon.OrbitalPeriod * 365.25)} 天)", new Font("Arial", 7), Brushes.Gray, startX 320, moonRowY);
                    row ;
                }
            }
        }

        private void DrawMoonInfo(Graphics g, int startX, int startY)
        {
            string moonInfo = "月球轨道信息:\n\n"
                             "• 真实月球轨道数据:\n"
                             "  - 平均距离: 384,400 km\n"
                             "  - 相对于地球: 0.00257 AU\n"
                             "  - 偏心率: 0.0549\n"
                             "  - 公转周期: 27.3 天\n\n"
                             "• 模拟中的显示:\n"
                             "  - 月球轨道已放大显示\n"
                             "  - 保持正确的椭圆形状\n"
                             "  - 相对速度正确\n\n"
                             "• 观察要点:\n"
                             "  - 月球每月绕地球一圈\n"
                             "  - 轨道是椭圆形\n"
                             "  - 在近地点运动较快";

            g.DrawString(moonInfo, new Font("Arial", 9), Brushes.LightGreen, startX, startY);
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            InitializeCanvas();
            Invalidate();
        }

        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            base.OnFormClosed(e);
            animationTimer?.Stop();
            graphics?.Dispose();
            canvas?.Dispose();
            labelFont?.Dispose();
            smallFont?.Dispose();

            foreach (var body in bodies)
            {
                body.Dispose();
            }
        }
    }

    public class CelestialBody : IDisposable
    {
        public string Name { get; set; }
        public float SemiMajorAxis { get; set; }
        public float OrbitalPeriod { get; set; }
        public float Radius { get; set; }
        public float Eccentricity { get; set; }
        public float Inclination { get; set; }
        public Color Color { get; set; }
        public bool IsSun { get; set; }
        public Moon Moon { get; private set; }
        public bool HasMoon => Moon != null;

        private double meanAnomaly;
        private List<PointF> positionHistory;
        private const int maxHistoryLength = 400; // 增加轨迹长度

        public CelestialBody(string name, float semiMajorAxis, float orbitalPeriod,
                           float radius, float eccentricity, float inclination, Color color, bool isSun = false)
        {
            Name = name;
            SemiMajorAxis = semiMajorAxis;
            OrbitalPeriod = orbitalPeriod;
            Radius = radius;
            Eccentricity = eccentricity;
            Inclination = inclination;
            Color = color;
            IsSun = isSun;

            meanAnomaly = new Random().NextDouble() * 2 * Math.PI;
            positionHistory = new List<PointF>();
        }

        public void AddMoon(Moon moon)
        {
            Moon = moon;
        }

        public void UpdatePosition(double timeStep)
        {
            // 更新行星位置
            if (!IsSun)
            {
                double meanMotion = 2 * Math.PI / OrbitalPeriod;
                meanAnomaly = meanMotion * timeStep;

                if (meanAnomaly > 2 * Math.PI)
                    meanAnomaly -= 2 * Math.PI;
            }

            // 更新月球位置(如果存在)
            Moon?.UpdatePosition(timeStep);
        }

        public PointF GetPosition(int centerX, int centerY, float scale)
        {
            if (IsSun) return new PointF(centerX, centerY);

            double eccentricAnomaly = SolveKeplerEquation(meanAnomaly, Eccentricity);

            double xOrbit = SemiMajorAxis * (Math.Cos(eccentricAnomaly) - Eccentricity);
            double yOrbit = SemiMajorAxis * Math.Sqrt(1 - Eccentricity * Eccentricity) * Math.Sin(eccentricAnomaly);

            float focusOffset = SemiMajorAxis * Eccentricity * scale;
            float x = centerX (float)xOrbit * scale focusOffset;
            float y = centerY (float)yOrbit * scale;

            PointF position = new PointF(x, y);

            positionHistory.Add(position);
            if (positionHistory.Count > maxHistoryLength)
            {
                positionHistory.RemoveAt(0);
            }

            return position;
        }

        public List<PointF> PositionHistory => positionHistory;

        private double SolveKeplerEquation(double meanAnomaly, double eccentricity)
        {
            double eccentricAnomaly = meanAnomaly;
            double delta = 1.0;
            double tolerance = 1e-8; // 提高精度
            int maxIterations = 100;
            int iterations = 0;

            while (Math.Abs(delta) > tolerance && iterations < maxIterations)
            {
                delta = (eccentricAnomaly - eccentricity * Math.Sin(eccentricAnomaly) - meanAnomaly) /
                        (1 - eccentricity * Math.Cos(eccentricAnomaly));
                eccentricAnomaly -= delta;
                iterations ;
            }

            return eccentricAnomaly;
        }

        public void Dispose()
        {
            positionHistory?.Clear();
            Moon?.Dispose();
        }
    }

    public class Moon : IDisposable
    {
        public string Name { get; set; }
        public float SemiMajorAxis { get; set; }
        public float OrbitalPeriod { get; set; }
        public float Radius { get; set; }
        public float Eccentricity { get; set; }
        public Color Color { get; set; }

        private double meanAnomaly;
        private List<PointF> positionHistory;
        private const int maxHistoryLength = 150;

        public Moon(string name, float semiMajorAxis, float orbitalPeriod,
                   float radius, float eccentricity, Color color)
        {
            Name = name;
            SemiMajorAxis = semiMajorAxis;
            OrbitalPeriod = orbitalPeriod;
            Radius = radius;
            Eccentricity = eccentricity;
            Color = color;

            meanAnomaly = new Random().NextDouble() * 2 * Math.PI;
            positionHistory = new List<PointF>();
        }

        public void UpdatePosition(double timeStep)
        {
            double meanMotion = 2 * Math.PI / OrbitalPeriod;
            meanAnomaly = meanMotion * timeStep;

            if (meanAnomaly > 2 * Math.PI)
                meanAnomaly -= 2 * Math.PI;
        }

        public PointF GetPositionRelativeToPlanet(PointF planetPosition, float scale)
        {
            // 使用正确的开普勒方程计算月球位置
            double eccentricAnomaly = SolveKeplerEquation(meanAnomaly, Eccentricity);

            // 计算在轨道平面上的坐标
            double xOrbit = SemiMajorAxis * (Math.Cos(eccentricAnomaly) - Eccentricity);
            double yOrbit = SemiMajorAxis * Math.Sqrt(1 - Eccentricity * Eccentricity) * Math.Sin(eccentricAnomaly);

            // 转换为屏幕坐标
            float focusOffset = SemiMajorAxis * Eccentricity * scale;
            float x = planetPosition.X (float)xOrbit * scale focusOffset;
            float y = planetPosition.Y (float)yOrbit * scale;

            PointF position = new PointF(x, y);

            positionHistory.Add(position);
            if (positionHistory.Count > maxHistoryLength)
            {
                positionHistory.RemoveAt(0);
            }

            return position;
        }

        public List<PointF> PositionHistory => positionHistory;

        private double SolveKeplerEquation(double meanAnomaly, double eccentricity)
        {
            double eccentricAnomaly = meanAnomaly;
            double delta = 1.0;
            double tolerance = 1e-8;
            int maxIterations = 100;
            int iterations = 0;

            while (Math.Abs(delta) > tolerance && iterations < maxIterations)
            {
                delta = (eccentricAnomaly - eccentricity * Math.Sin(eccentricAnomaly) - meanAnomaly) /
                        (1 - eccentricity * Math.Cos(eccentricAnomaly));
                eccentricAnomaly -= delta;
                iterations ;
            }

            return eccentricAnomaly;
        }

        public void Dispose()
        {
            positionHistory?.Clear();
        }
    }

  
}

实例下载地址

太阳系行星运行模拟

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警