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<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.7+2.4*((double)j/(double)width);
y= -1.2+2.4*((double)i/(double)height);
// 0 <= r <= 50の値が返る
r=mandel(x,y);
// r=50の時に黒(0,0,0), r=0の時にほぼ白(250,250,250)とする.
System.out.println((250-r*5)+" "+(250-r*5)+" "+(250-r*5));
}
}
}
}
このプログラムを 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 は以下のようになる.
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になる),
System.out.println(((50-r)*71)%256+" "+((50-r)*111)%256+" "+((50-r)*97)%256);
の部分を書き換えて(71, 111, 97あたりの数字),より綺麗な画像を作成するように書き変えなさい.
/home/ktanaka/bin/report618 1を実行してください.
締切は 6/25 の 21:00まで.
今回の課題は前回の課題と比べて自由度が大きいので,偶然同じ画像を作るプ ログラムが提出される確率はほとんど無いと期待している.