開発環境 Microsoft Visual C# 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Windows Game (4.0)
プロジェクト名 AstroSim1

Game1.cs
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
 
namespace AstroSim1
{
    class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        BasicEffect effect;
        VertexBuffer vertexBuffer;
 
        const double r0 = 1.49597870700e11; // 平均公転半径(m)
        const double GM = 1.32712442099e20; // 日心重力定数(m3s-2)
        double earthPosX = r0;
        double earthPosY = 0;
        double earthDirX = 0;
        double earthDirY = 29780; // 軌道速度(m/s)
 
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredBackBufferWidth = 1280;
            graphics.PreferredBackBufferHeight = 720;
            IsMouseVisible = true;
        }
 
        protected override void LoadContent()
        {
            effect = new BasicEffect(GraphicsDevice);
            effect.VertexColorEnabled = true;
            effect.View = Matrix.CreateLookAt(
                new Vector3(0, 0, (float)(r0 * 3.0)), Vector3.Zero, Vector3.Up);
            effect.Projection = Matrix.CreatePerspectiveFieldOfView(
                MathHelper.ToRadians(45), GraphicsDevice.Viewport.AspectRatio, 1, (float)(r0 * 5.0));
 
            VertexPositionColor[] vertices = new VertexPositionColor[365 + 1];
 
            for (int sec = 0; sec <= 31556926; sec++) // 365.2422 * 24 * 60 * 60 = 31556926.08
            {
                double r = Math.Sqrt(earthPosX * earthPosX + earthPosY * earthPosY);
                double f = GM / (r * r);
                double fx = f * (-earthPosX / r);
                double fy = f * (-earthPosY / r);
 
                if (sec % 86400 == 0)
                {
                    vertices[sec / 86400] = new VertexPositionColor(
                        new Vector3((float)earthPosX, (float)earthPosY, 0), Color.White);
                    Console.WriteLine(string.Format("day={0} x={1:f1} y={2:f1} r={3}",
                        sec / 86400, earthPosX, earthPosY, r));
                }
 
                earthDirX += fx;
                earthDirY += fy;
                earthPosX += earthDirX;
                earthPosY += earthDirY;
            }
            Console.WriteLine(string.Format("day={0:f4} x={1:f1} y={2:f1}",
                31556926.0 / 86400.0, earthPosX, earthPosY));
 
            vertexBuffer = new VertexBuffer(GraphicsDevice,
                typeof(VertexPositionColor), vertices.Length, BufferUsage.WriteOnly);
            vertexBuffer.SetData(vertices);
 
            base.LoadContent();
        }
 
        protected override void Update(GameTime gameTime)
        {
            KeyboardState kState = Keyboard.GetState();
            if (kState.IsKeyDown(Keys.Escape)) Exit();
            base.Update(gameTime);
        }
 
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            GraphicsDevice.BlendState = BlendState.AlphaBlend;
 
            GraphicsDevice.SetVertexBuffer(vertexBuffer);
            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                GraphicsDevice.DrawPrimitives(PrimitiveType.LineStrip, 0, 365);
            }
 
            base.Draw(gameTime);
        }
    }
}
 
最終更新:2012年12月29日 15:08