/////////////////////////////////////////////////////////////////////// // ケプラーの法則をシミュレーションする Java Applet // By Takuichi Hirano (平野 拓一) import java.awt.*; /////////////////////////////////////////////////////////////////////// // 2次元ベクトル class Vector { double x; double y; } /////////////////////////////////////////////////////////////////////// // 星クラス class Star { Vector loc; // 位置 Vector velo; // 速度 double mass; // 質量 double r; // この星の(表示する時の)半径 // コンストラクタ Star(double x, double y, double vx, double vy, double mass, double r) { loc = new Vector(); velo = new Vector(); this.loc.x = x; this.loc.y = y; this.velo.x = vx; this.velo.y = vy; this.mass = mass; this.r = r; } } /////////////////////////////////////////////////////////////////////// // 自分のパネルクラスを定義する class SpaceCanvas extends Canvas implements Runnable { private Kepler gravity; private Thread animation; private Star sun, earth; private final double dt = 0.5; // 微小時間 private final double G = 1.0; // 万有引力定数 // コンストラクタ public SpaceCanvas(Kepler grav) { resize(200, 200); setForeground(Color.white); setBackground(Color.black); this.gravity = grav; sun = new Star(size().width/2.0, size().height/2.0, 0, 0, 10000, 10); earth = new Star(size().width/2.0 + 90, size().height/2.0, 0, -5, 10, 5); } public void run() { while (true) { move(); try { Thread.sleep(25); } catch (InterruptedException e) { break; } } } public void move() { /* 万有引力の法則により、座標を更新する */ double rx, ry; double ax, ay; double r3; rx = earth.loc.x - sun.loc.x; ry = earth.loc.y - sun.loc.y; r3 = Math.pow(rx*rx + ry*ry, 3/(double)2); rx /= r3; ry /= r3; // 位置と速度の更新 // sun.velo.x = sun.velo.x + G * earth.mass * rx * dt; // sun.velo.y = sun.velo.y + G * earth.mass * ry * dt; earth.velo.x = earth.velo.x - G * sun.mass * rx * dt; earth.velo.y = earth.velo.y - G * sun.mass * ry * dt; // sun.loc.x += sun.velo.x; // sun.loc.y += sun.velo.y; earth.loc.x += earth.velo.x; earth.loc.y += earth.velo.y; repaint(); } Image offscreen; Dimension offscreensize; Graphics offgraphics; public synchronized void update(Graphics g) { /* このパネルを再描画する */ Dimension d = size(); /* 初めてのときの初期化 */ if((offscreen == null) || (d.width != offscreensize.width) || (d.height != offscreensize.height)) { offscreen = createImage(d.width, d.height); offscreensize = d; offgraphics = offscreen.getGraphics(); offgraphics.setFont(getFont()); } /* キャンバスをクリア */ offgraphics.setColor(getBackground()); offgraphics.fillRect(0, 0, d.width, d.height); offgraphics.setColor(Color.red); int diam = 2*(int)sun.r; offgraphics.fillOval((int)sun.loc.x-(int)sun.r, (int)sun.loc.y-(int)sun.r, diam, diam); offgraphics.setColor(Color.blue); diam = 2*(int)earth.r; offgraphics.fillOval((int)earth.loc.x-(int)earth.r, (int)earth.loc.y-(int)earth.r, diam, diam); g.drawImage(offscreen, 0, 0, null); } public void start() { animation = new Thread(this); /* スレッドを新たに作る */ animation.start(); } public void stop() { animation.stop(); } } // // メインクラス (Kepler) // public class Kepler extends java.applet.Applet { int c = 0; SpaceCanvas canvas; // appletviewer やブラウザに読み込まれたときに実行 public void init() { setLayout(new BorderLayout()); // レイアウトマネージャの設定 canvas = new SpaceCanvas(this); add("Center", canvas); resize(200, 200); } // ウィンドウが隠れたりして再描画命令がきたときに実行 public void paint(Graphics g) { } public void start() { /* パネルのスレッドをスタートさせる */ canvas.start(); } public void stop() { /* パネルのスレッドをストップさせる */ canvas.stop(); } public boolean action(Event evt, Object obj) { return false; } }