using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;namespace SunEarthMoon
{
    public partial class Form1 : Form
    {
        private Graphics g;
        private const int sunr = 100;  //太阳的半径
        private const int earthr = 60; //地球的半径
        private const int moonr = 40; // 月亮的半径
        private const int dissunearth = 260;  // 太阳到地球的距离
        private const int disearthmoon = 150; //地球到月球的距离
        double earthradian =360d/365d*Math.PI/180;  // 地球一天旋转角度
        double  moonradian = 360d / 30d * Math.PI / 180;  // 月球一天旋转角度
        Point sunp = new Point(0, 0);  //设置太阳的位置在原点
        Point earthp, moonp;  //地球,月球的位置
        int earthCount = 1;  //地球旋转的天数
        int moonCount = 1;  //月球旋转的天数
         public Form1()
        {
            InitializeComponent();
        }        private void InitGraphics()
        {
            g = this.CreateGraphics();
            g.Clear(Color.White);
            drawSence();
        }
        
        /// <summary>
        /// 点的平移变换
        /// </summary>
        /// <param name="s">要平移的点</param>
        /// <param name="deltax">要平移的X值</param>
        /// <param name="deltay">要平移的Y值</param>
        /// <returns>平移后的点</returns>
        private  Point translatePoint(Point s, int deltax, int deltay)
        {
            s.X += deltax;
            s.Y += deltay;
            return s;
        }        private  Point rotatePoint(Point s,double  radian)
        {
            s.X =(int)( s.X * Math.Cos(radian) - s.Y * Math.Sin(radian));
            s.Y = (int)(s.X * Math.Sin(radian) + s.Y * Math.Cos(radian));
            return s;
        }        private void  drawCircel(Point s,int r)
        {
            g.DrawEllipse(new Pen(Color.Blue), s.X, s.Y, r, r);
        
        }        
        private void drawSence()
        {
            
            int x = this.Width;
            int y = this.Height;            //画坐标的箭头
            AdjustableArrowCap arrow = new AdjustableArrowCap(4, 4, true);
            Pen myPen = new Pen(Color.Black, 1);
            myPen.CustomEndCap = arrow;
            //确定坐标原点
            g.TranslateTransform(x / 2, y / 2);
            // 画X坐标轴
            g.DrawLine(myPen, -x / 2, 0, x / 2, 0);
            //画Y坐标轴
            g.DrawLine(myPen, 0, y / 2, 0, -y / 2);            earthp = translatePoint(sunp, dissunearth, 0);
            earthp = rotatePoint(earthp, earthradian * earthCount);
            if (earthCount == 365)
            {
                earthCount = 1;
            }
            else
            {
                earthCount++;
            }
            moonp = rotatePoint(new Point(disearthmoon, 0), moonradian * moonCount);
            moonp = translatePoint(moonp, earthp.X, earthp.Y);
            if (moonCount == 30)
            {
                moonCount = 1;
            }
            else
            {
                moonCount++;
            }
            drawCircel(sunp, sunr);
            drawCircel(earthp, earthr);
            drawCircel(moonp, moonr);
        }        private void timer1_Tick(object sender, EventArgs e)
        {
            this.Refresh();
        }        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            InitGraphics();
        }
    }
}
运行后地球和月亮的运行轨迹都是倒立的“8”,并不是地球绕太阳,月球绕地球旋转。
估计应该是求旋转后的点的位置出错,但是不知道怎么改,望指教!!

解决方案 »

  1.   

    回复2楼:结贴率这个问题我也没注意到,可能是我人品打爆发,CSDN给了多久了几个百分点吧!呵呵
      

  2.   

    圆的公式怎么这个样子的?
    几个地方不对,改了下,正常了public partial class Form3 : Form
        {
            private Graphics g;
            private const int sunr = 100;  //太阳的半径
            private const int earthr = 60; //地球的半径
            private const int moonr = 40; // 月亮的半径
            private const int dissunearth = 260;  // 太阳到地球的距离
            private const int disearthmoon = 150; //地球到月球的距离
            double earthradian = 360d / 365d * Math.PI / 180;  // 地球一天旋转角度
            double moonradian = 360d / 30d * Math.PI / 180;  // 月球一天旋转角度
            Point sunp = new Point(0, 0);  //设置太阳的位置在原点
            Point earthp, moonp;  //地球,月球的位置
            int earthCount = 1;  //地球旋转的天数
            int moonCount = 1;  //月球旋转的天数
            public Form3()
            {
                InitializeComponent();        }        private void InitGraphics()
            {
                g = this.CreateGraphics();
                g.Clear(Color.White);
                drawSence();
            }        /// <summary>
            /// 点的平移变换
            /// </summary>
            /// <param name="s">要平移的点</param>
            /// <param name="deltax">要平移的X值</param>
            /// <param name="deltay">要平移的Y值</param>
            /// <returns>平移后的点</returns>
            private Point translatePoint(Point s, int deltax, int deltay)
            {
                s.X += deltax;
                s.Y += deltay;
                return s;
            }
            //这里改了
            private Point rotatePoint(int r, double radian)
            {
                //圆公式不对
                //s.X = (int)(s.X * Math.Cos(radian) - s.Y * Math.Sin(radian));
                //s.Y = (int)(s.X * Math.Sin(radian) + s.Y * Math.Cos(radian));
                
                Point s = new Point();
                s.X = (int)(r * Math.Cos(radian));
                s.Y = (int)(r * Math.Sin(radian));
                return s;
            }        private void drawCircel(Point s, int r)
            {
                g.DrawEllipse(new Pen(Color.Blue), s.X - r / 2, s.Y - r / 2, r, r); //这里改了
            }
            private void drawSence()
            {            int x = this.Width;
                int y = this.Height;            //画坐标的箭头
                AdjustableArrowCap arrow = new AdjustableArrowCap(4, 4, true);
                Pen myPen = new Pen(Color.Black, 1);
                myPen.CustomEndCap = arrow;
                //确定坐标原点
                g.TranslateTransform(x / 2, y / 2);
                // 画X坐标轴
                g.DrawLine(myPen, -x / 2, 0, x / 2, 0);
                //画Y坐标轴
                g.DrawLine(myPen, 0, y / 2, 0, -y / 2);            earthp = translatePoint(sunp, dissunearth, 0);
                earthp = rotatePoint(dissunearth, earthradian * earthCount);//这里改了
                if (earthCount == 365)
                {
                    earthCount = 1;
                }
                else
                {
                    earthCount++;
                }
                moonp = rotatePoint(disearthmoon, moonradian * moonCount);//这里改了
                moonp = translatePoint(moonp, earthp.X, earthp.Y);
                if (moonCount == 30)
                {
                    moonCount = 1;
                }
                else
                {
                    moonCount++;
                }
                
                drawCircel(sunp, sunr);
                drawCircel(earthp, earthr);
                drawCircel(moonp, moonr);
            }        private void timer1_Tick(object sender, EventArgs e)
            {
                this.Refresh();
            }        private void Form3_Paint(object sender, PaintEventArgs e)
            {
                InitGraphics();
            }        private void Form3_Load(object sender, EventArgs e)
            {
                this.timer1.Interval = 10;
                this.timer1.Start();
            }
        }
      

  3.   

    恩,7楼的方法可以。但是我们在学习计算机图形学,学习点的平移算法,主要是
                s.X =(int)( s.X * Math.Cos(radian) - s.Y * Math.Sin(radian));
                s.Y = (int)(s.X * Math.Sin(radian) + s.Y * Math.Cos(radian));
                return s;这个算法的设计,不过还是很感谢7楼的朋友
      

  4.   


    本来就是个示意图,估计目的也不在于普及天文知识
    还要考虑进动,那章动要不要考虑?
    视图里天体半径比首先也不对,当然,如果对了的话这么大尺度坐标显示器也放不下的.
    光一个椭圆轨道开普勒就研究了多少年?
    让一个刚学gdi的人实现这些,过于吹毛求疵了.