06020
1年後期>report6


Java Applet/AWTについて学習し、Java Appletのオリジナルプログラムを作成し解説せよ。

1.Orbit0

1-1.プログラム
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import java.applet.*;
import java.awt.*;

/* <applet code="Orbit0" width=200 height=200> 
   </applet>  */

public class Orbit0 extends Applet implements Runnable{

    int ex,ey,mx,my;        //earth_x,y   moon_x,y                        
    double ek,mk;
    Thread t;
    Image ibuf;
    Graphics gbuf;          //グラフィックの設定   

    public void init(){

        t=new Thread(this);
        t.start();
        ibuf=createImage(200,200);       //イメージの大きさ
        gbuf=ibuf.getGraphics();         //ダブルバッファ
        ek=0;mk=0;                       //ek,mkを初期化                
    }

    public void run(){

        try{
            while(true){
                repaint();
                t.sleep(100);
            }
        }
        catch(Exception e){
        }
    }

    public void update(Graphics g){
        paint(g);
    }

    public void paint(Graphics g){

        gbuf.setColor(Color.black);     //背景の設定                        
        gbuf.fillRect(0,0,200,200);
        gbuf.setColor(Color.blue);      //十字の青い線                        
        gbuf.drawLine(0,100,200,100);
        gbuf.drawLine(100,0,100,200);
        gbuf.setColor(Color.orange);    //地球の公転円          
        gbuf.drawOval(30,30,140,140);

        ex=(int)(70*Math.sin(ek*Math.PI/180));    //earth  PI=3.14...=π
        ey=(int)(70*Math.cos(ek*Math.PI/180));
        mx=(int)(20*Math.sin(mk*Math.PI/180));    //moon                     
        my=(int)(20*Math.cos(mk*Math.PI/180));

        gbuf.setColor(Color.red);           //太陽                            
        gbuf.fillOval(85,85,31,31);
        gbuf.setColor(Color.green);         //地球                           
        gbuf.fillOval(94+ex,94+ey,13,13);
        gbuf.setColor(Color.lightGray);     //月                             
        gbuf.fillOval(97+ex+mx,97+ey+my,7,7);

        g.drawImage(ibuf,0,0,this);

        ek=ek+0.986; if ( ek >360 ) ek=ek-360;      //360は角度
        mk=mk+13.18; if ( mk >360 ) mk=mk-360;
    }
}

1-2.実行結果
Orbit0

1-3.考察
9行目、ex,eyは地球(earth)のx座標,y座標。10行目、mx,myは月(moon)のx座標,y座標である。
10行目、ekは地球のx,yを求めるための変化する数で、速度のようなもの。mkも同じように月の速度のようなものである。
11行目、Threadは画面全体の設定である。
12,13行目はグラフィックの設定である。このアプレットはダブルバッファを使って、なめらかに表示させている。

15~22行はアプレットの初期設定である。

24~34行はアプレットを動作に関わるメソッドである。
while(true)で無限ループを作り、アプレットをずっと動作させる。
また、t.sleepは、現在実行中のスレッドを指定されたミリ秒数の間、スリープ (一時的に実行を停止) させるもので、この場合は0.1秒で一つの画像を描画している。
例外が起きた時は何も設定していない。

36,37行目はpaint(g)のアップデートを行っている。
40行目以降はグラフィックのメソッドである。
42~48行は背景などの動かない図形の設定である。
42,43行目は背景の設定である。色は黒であり、x=0,y=0から始まり、x=200,y=200までの長方形を描く。
44~46行までは十字の青い線の設定である。色は青で、45行目が横の線、46行目が縦の線を描く。
47,48行目は地球が回るオレンジ色の円の設定である。x=30,y=30から始まり、x=140,y=140までの円を描く。

50~53行は地球、月のx,y座標を決定している。数学的な内容なのでまとめて後述する。

55,56行目では太陽の設定である。ちなみにこのアプレットでは太陽は動かない
57,58行目は地球の位置を決めている。細かい説明は後述する。
59,60行目は月の位置を決めている。

62行目はイメージを描いている。

64,65行目はek,mkの値を設定している。


数学的なこと
 ex=(int)(70*Math.sin(ek*Math.PI/180));
 ey=(int)(70*Math.cos(ek*Math.PI/180));
 mx=(int)(20*Math.sin(mk*Math.PI/180));
 my=(int)(20*Math.cos(mk*Math.PI/180));
exは地球のx座標を決定する。グラフィックで表すからint型であり、70は中心の太陽(x,y)=(100,100)からの距離、Math.sinはsin関数を呼び出す。eyは地球のy座標を決定する。exとeyは-70~70の値をとる。
また、月のmx,myも同様である。mxとmyは-20~20の値をとる。

パソコンではsin,cosのパラメータに角度(degree)ではなくラジアン(radian)という単位を使わないといけない。よって、sin30°=1/2 等とはできない。
角度からラジアン、ラジアンから角度への変換の公式は以下のようになる。
 角度(degree)→ラジアン(radian)に変換
   radian = Math.PI/180 * degree
 ラジアン(radian)→角度(degree)に変換
   degree = radian / (Math.PI/180)

さらに、
 ek=ek+0.986; if ( ek >360 ) ek=ek-360;
 mk=mk+13.18; if ( mk >360 ) mk=mk-360;
というように1回の処理でekは0.986ずつ、mkは13.18ずつ増えていく。

例えば、1回目の処理では、ek=mk=0
 ex=(int)(70*Math.sin(ek*Math.PI/180)) = 0
 ey=(int)(70*Math.cos(ek*Math.PI/180)) = 70
 mx=(int)(20*Math.sin(mk*Math.PI/180)) = 0
 my=(int)(20*Math.cos(mk*Math.PI/180)) = 20
座標の関数より
 gbuf.fillOval(94+ex,94+ey,13,13);
 gbuf.fillOval(97+ex+mx,97+ey+my,7,7);
よって地球の位置はxy=(94,164)、月の位置はxy=(97,187)となる。
ここで、地球と月のx座標がずれるのは円の中心からの距離ではないからである。
一回一回の描画の連続により、一秒間で10コマの動画になる。

ek=ek+0.986となっているのは地球の公転周期が365.25日であるからで、  (360÷365.25=0.9856...)
mk=mk+13.18となっているのは月の公転周期が27.32日であるためである。 (360÷27.32=13.177...)
ちなみに0.1秒で1日なので、1秒で十日、約36秒で地球が一回りする。


アプレット参考HPhttp://www5.ocn.ne.jp/~crachica/index.html
様々な種類のアプレットがあって面白いです。



ちゃんと解析するとわりと簡単なアプレットだったが、数学で少してこずった。でも、ちゃんと分かった時は気持ちがよかった。