6/25 プログラミング(3)


前回の補足,復習


5/21の課題について


前々回の課題について

惜しかった例
class Grad{
    public static void main(String[] args){
        int width=128, height=128;
        System.out.println("P3 "+width+" "+height+" 255");
        int i,j;
        for(i=0;i< height;i=i+1){
            for(j=0;j< width;j=j+1){
                System.out.println((i*2)+" 0 "+(254-j*2));
            }
        }
    }
}
「画面の左上(i=0, j=0)でほぼ青(0 0 254),画面の右下(i=127, j=127)で ほぼ赤(254 0 0)」という条件は満たしているが,出力結果は,
となり,正解の
grad0.gif
とは異なっている.

前回の課題について


今日の目標


はいぱーワークブックへの補足

PPMファイルを複数出力して,それから convert してアニメーション gif ファイルを 作成することを考える.プログラムを少しずつ変更して,
javac mandel.java
java mandel > mandel0.ppm
(mandel.javaを編集.保存)
javac mandel.java
java mandel > mandel1.ppm
(mandel.javaを編集.保存)
...
javac mandel.java
java mandel > mandel9.ppm
(mandel.javaを編集.保存)
のようにしてもできるが,直接ファイルに指定する方法を試してみる. ファイルに出力するには,まず,
      java.io.PrintWriter ps=new java.io.PrintWriter(new java.io.FileWriter("mandel"+k+".ppm"));
のようにして,ファイル名("mandel"+k+".ppm")からFileWriterを作り,それ から PrintWriterを作る.
「作る」というのは「オブジェクトの生成」にあたり,演算子 new で実現さ れるが,この講義の範囲を超えるので詳しい説明は省略する.興味のある人は, あたりを参照すること.

これまで,

 System.out.println( 出力したい文字列 );
としてきたのを,
 ps.println( 出力したい文字列 );
とするとファイルへの出力に変る.
これは,変数 ps に入っているjava.io.PrintWriter型のオブジェクトのメソッド println を呼び出しているという動作だが,ここでは詳しい説明は省略する.

出力を終えたら,ファイルを閉じる必要がある.

ps.close();
を実行する.

プログラム

class Mandel{
  // 実数を引数(パラメタ)に持つメソッド mandel の定義
  static int mandel(double x, double y){
    double zr=0, zi=0,new_zr;
    int i;
    for(i=0;i<50;i=i+1){
      if(zr*zr+zi*zi>4.0) { // |Zi|>2.0 の時は発散と判断
        return i;
      }
       // 複素数の計算
       // (zr+zi*i)*(zr+zi*i)+x+y*i=(zr*zr-zi*zi+x)+(2*zr*zi+y)*i
      new_zr=zr*zr-zi*zi+x;
      zi=2*zr*zi+y;
      zr=new_zr;
    }
    return 50;
  }
    // 入出力関係でエラーが発生する可能性があるので,
    // throws java.io.IOException をつける.
  public static void main(String[] args) throws java.io.IOException{
    int width=256, height=256;
    int k;
    for(k=0;k<10;k++){
        // ファイルに出力する時は,ファイル名("mandel"+k+".ppm")から
        //  FileWriterを作り,それから PrintWriterを作る
      java.io.PrintWriter ps=new java.io.PrintWriter(new java.io.FileWriter("mandel"+k+".ppm"));
        // マンデルブロー集合を計算する範囲のスケール
        // 3e-0.8k なので,kが0の時は3
      double scale=3.0*Math.exp(-(double)k*0.8);
        // ファイルへの出力
      ps.println("P3 "+width+" "+height+" 255");
      int i,j,r;
      double x, y;
      for(i=0;i<height;i=i+1){
	for(j=0;j<width;j=j+1){
	  // -1.7 <= x < 0.7, -1.2 <= y < 1.2の範囲で計算
	  // 実数(double)から整数(int)への変換は「(double)整数式」
	  // のようにおこなう.
	  x= -1.2525 -scale*0.5+scale*((double)j/(double)width);
	  y= -0.3425 -scale*0.5+scale*((double)i/(double)height);
	  // 0 <= r <= 50の値が返る
	  r=mandel(x,y);
	  // r=50の時に青(0,0,255), r=0の時にほぼ白(250,250,250)とする.
	    // ファイルへの出力
	  ps.println((250-r*5)+" "+(250-r*5)+" 250");
	}
      }
        // ファイルストリームを閉じる
      ps.close();
    }
  }
}
これを実行すると,mandel0.ppm, mandel1.ppm, ..., mandel9.ppmというファ イルができる.
convert -delay 40 mandel[0-9].ppm mandel-animation.gif
のように実行すると,0.4秒間隔(-delay のパラメータは 1/100秒単位で指定)で, mandel[0-9].gif を次々に表示していく.以下のような画像が現れる.
mandel-animation.gif
このアニメーションはロードされた直後に一度動くようにしてあるので, Reload ボタンを押すと動き出す.

convertコマンドは Unix マシンに slogin してから実行すると,実行も速いし,作成される gif ファイルも小さくなる



今日の課題

  • はいぱーワークブック 21 プログラミングの世界を自習した上で, 今日の課題(6/25 13:30以降有効)のページに行って指示に従うこと.
  • 提出期限は 7/11(金) 21:00まで