7/10 Java プログラミング第2回


最近の計算機関連のニュースから


共通試験について


前回の課題

以下のプログラム
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("255 255 "+(j*2));
      }
    }
  }
}
の,
        System.out.println("255 255 "+(j*2));
の行を変更して,
grad0.gif
のような画像ファイルを作成するプログラムにしなさい.

解答例

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+j)+" 0 "+(254-i-j));
      }
    }
  }
}

総評


結果

今日の目標


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

今日の課題をこなすために,マンデルブロー集合の定義と,マンデルブロー 集合を計算する簡単なプログラムの説明をおこなう.

マンデルブロー集合とは

ある複素数 C を与えた時,
Z0=0
Zn+1=Zn*Zn+C
として, 複素数列{Zn}が定義できる.ここで,n->∞としたとき, |Zn|が発散しないようなCの集合をマンデルブロー集合という.

マンデルブロー集合は,集合の境界が複雑な形をしていて, 拡大をしても元の 図形と同じような複雑度を保っている.このような自己相似のことを総称して フラクタルと呼ぶが,マンデルブロー集合はフラクタルな図形の中ではもっと も有名である.

マンデルブロー集合は定義に無限回の繰り返しを含んでいるため, 計算機上 で正確に描くのは,困難である.そこで, 一般には

という近似を使って計算できる.以下は, この近似を用いてマンデルブロー集合を 計算するプログラムである(マンデルブロー集合は画像の黒い部分で表される).なお,「//」は注釈(コメント)の始まりを表す.

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;
  }
  public static void main(String[] args){
    int width=256, height=256;
    System.out.println("P3 "+width+" "+height+" 255");
    int i,j,r;
    double x, y;
    for(i=0;i
このプログラムを Mandel.java というファイルに保存して,
javac Mandel.java
java Mandel > mandel.ppm
と実行すると,mandel.ppm というファイルが得られる.これは,
display mandel.ppm
で見ることもできるし(display コマンドの終了は,左ボタンでメニューを出してFile->Quitを選択),
convert mandel.ppm mandel.gif
として gif 形式に変換して,Netscape Navigatorで見ることもできる. できた mandel.gif は以下のようになる.
mandel.gif
        System.out.println((250-r*5)+" "+(250-r*5)+" "+(250-r*5));
の行を,たとえば
        System.out.println(((50-r)*71)%256+" "+((50-r)*111)%256+" "+((50-r)*97)%256);
とすると(「%」は剰余(mod)を表す演算子, 256で割った余りは 0-255になる),
mandel-color.gif
のようなカラーの絵が得られる.

今日の課題


  1. 上のプログラムwo, ~/jousho00 以下に Mandel.java という名前で保存して, コンパイル,実行してみなさい.
  2. 上のプログラムは,-1.7 <= x < 0.7, -1.2 <= y < 1.2の範囲でマンデ ルブロー集合を計算しているが, より狭い範囲(元のプログラムよりも縦横そ れぞれ 1/4 以下)を計算するように Mandel.java を書き換えなさい(範囲の選 び方を間違えると,境界部分が含まれないつまらない画像になってしまうので, 注意すること,元のプログラムの画像で左上の点が(-1.7,-1.2), 右下の点が(0.7, 1.2)なので,複雑そうな所を見当をつけてそこを拡大すると良い).
  3. 上のカラー画像は色使いにセンスがないので,Mandel.java
            System.out.println(((50-r)*71)%256+" "+((50-r)*111)%256+" "+((50-r)*97)%256);
    
    の部分を書き換えて(71, 111, 97あたりの数字),より綺麗な画像を作成するように書き変えなさい.
すべての書き換えをおこない.プログラムがちゃんと動くことを確認したら,
/home/ktanaka/bin/report710 1
を実行してください.

締切は 7/10 の 21:00まで.

今回の課題は前回の課題と比べて自由度が大きいので,偶然同じ画像を作るプ ログラムが提出される確率はほとんど無いと期待している.


ktanaka at ecc.u-tokyo.ac.jp