プログラム
import java.applet.Applet; import java.awt.*; import java.awt.image.*; import java.awt.event.*; public class Julia extends Applet implements ItemListener,ActionListener,MouseListener,MouseMotionListener{ int SIZE=200; int MSIZE=200; int X0=10,Y0=150; int X1=X0+SIZE+20,Y1=150; Choice choice1,choice2,choice3,choice4; Label label1,label2,label3,label4,label5, label6,label7,label8,label9; Button button1,button2,button3,button4,button5; TextField tfield1,tfield2,tfield3,tfield4,tfield5; Image img_mandel; //Cの実数部、Cの虚数部 double creal,cimag; //Z0の実数部の中心、Z0の虚数部の中心、表示の範囲 double z0real,z0imag,width; //同上のクリックによる変化分 double z0real_d,z0imag_d; //繰返し回数の上限、カラー階調数、クリック倍率 int count_max,color_base,ratio; int type; //着色方式 public class Complex{ double re,im; //実数部と虚数部 public Complex(){ //コンストラクタ re=0.0; im=0.0; } public Complex(double a, double b){ //コンストラクタ re=a; im=b; } public Complex add(Complex a){ //加算 return new Complex(this.re+a.re, this.im+a.im); } public Complex sqr(){ //二乗 return new Complex( (this.re + this.im)*(this.re - this.im), 2 * this.re * this.im); } public double abs2(){ //絶対値の二乗 return this.re * this.re + this.im * this.im; } public double arg(){ //偏角(argument) return Math.atan(this.im / this.re); } } public void init(){ //------------------------ GUI関係準備 ------------------------ // 中略 //------------------------ 初期化設定 ------------------------ // 中略 //-------------------- Mandelbrot図形準備 -------------------- double value; int count; Complex c=new Complex(); int[] pixels=new int[MSIZE*MSIZE]; for(int x=-MSIZE/2;x<MSIZE/2;x++){ c.re=x*2.5/MSIZE-0.75; for(int y=-MSIZE/2;y<MSIZE/2;y++){ c.im=y*2.5/MSIZE; Complex z=new Complex(); count=0; do{ z=z.sqr().add(c); value=z.abs2(); count++; if(count>64){ count=-1; break; } } while(value<4.0); Color color=countToColorA(count,32); pixels[(y+MSIZE/2)*MSIZE+x+MSIZE/2]=color.getRGB(); } } img_mandel=createImage( new MemoryImageSource(MSIZE,MSIZE,pixels,0,MSIZE)); } // ----------------------- GUI関係メソッド ----------------------- //チョイスが変更になった場合のメソッド public void itemStateChanged(ItemEvent ie){ //中略 } //ボタンをクリックしたときのメソッド public void actionPerformed(ActionEvent ae){ // 中略 } public void mouseDragged(MouseEvent me){} //マウスをクリックしたときのメソッド public void mousePressed(MouseEvent me){ int x=me.getX(); int y=me.getY(); if(x>X0 && x<X0+SIZE && y>Y0 && y<Y0+SIZE){ //ジュリア画像内 z0real_d=(x-(X0+SIZE/2))*width/SIZE; //変化分を記憶させる z0real+=z0real_d; z0imag_d=(y-(Y0+SIZE/2))*width/SIZE; //変化分を記憶させる z0imag-=z0imag_d; width/=ratio; tfield3.setText(String.valueOf((float)z0real)); tfield4.setText(String.valueOf((float)z0imag)); tfield5.setText(String.valueOf((float)width)); drawJulia(); } //マンデルブロー画像内 if(x>X1 && x<X1+SIZE && y>Y1 && y<Y1+SIZE){ creal=(x-X1)*2.5/MSIZE-2.0; cimag=-(y-Y1)*2.5/MSIZE+1.25; tfield1.setText(String.valueOf((float)creal)); tfield2.setText(String.valueOf((float)cimag)); drawMandel(); drawJulia(); } } public void mouseMoved(MouseEvent me){} public void mouseEntered(MouseEvent me){} public void mouseExited(MouseEvent me){} public void mouseClicked(MouseEvent me){} public void mouseReleased(MouseEvent me){} //数値をカラーに変換するメソッドA private Color countToColorA(int count, int base){ int r,g,b; if(count<0) return Color.black; int d=(count % base)*256/base; int m=(int)(d/42.667); switch(m){ //青→シアン case 0: r=0; g=6*d; b=255; break; //シアン→緑 case 1: r=0; g=255; b=255-6*(d-43);break; //緑→黄 case 2: r=6*(d-86); g=255; b=0; break; //黄→赤 case 3: r=255; g=255-6*(d-129);b=0; break; //赤→マゼンタ case 4: r=255; g=0; b=6*(d-171); break; //マゼンタ→青 case 5: r=255-6*(d-214); g=0; b=255; break; default: r=0; g=0; b=0; break; } return new Color(r,g,b); } //数値をカラーに変換するメソッドB private Color countToColorB(int count, int base){ int r,g,b; if(count<0) return Color.black; int d=(count % base)*256/base; int m=d/32; switch(m){ //青→マゼンタ case 0: r=63+6*d; g=63; b=255; break; //マゼンタ→白 case 1: r=255; g=63+6*(d-32); b=255; break; //白→シアン case 2: r=255-6*(d-64);g=255; b=255; break; //シアン→緑 case 3: r=63; g=255; b=255-6*(d-96);break; //緑→黄 case 4: r=63+6*(d-128);g=255; b=63; break; //黄→赤 case 5: r=255; g=255-6*(d-160);b=63; break; //赤→黒 case 6: r=255-6*(d-192);g=63; b=63; break; //黒→青 case 7: r=63; g=63; b=63+6*(d-224);break; default: r=0; g=0; b=0; break; } return new Color(r,g,b); } //ジュリア図形を描画するメソッド private void drawJulia(){ Graphics g=getGraphics(); int count; int x,y; double zr,zi; double value=0.0; double step=width/SIZE; Complex c=new Complex(creal,cimag); Complex z=new Complex(); g.setColor(Color.black); g.drawString("ジュリア図形描画中",X0+SIZE+20,Y0+300); for(x=-SIZE/2;x<=SIZE/2;x++){ zr=x*step+z0real; for(y=-SIZE/2;y<=SIZE/2;y++){ zi=y*step+z0imag; z=new Complex(zr,zi); count=0; do{ z=z.sqr().add(c); //Julia集合の繰返し演算(Z=Z*Z+C) value=z.abs2(); //絶対値(の二乗)の計算 count++; if(count>count_max){ //発散しないと判断 count=-1; break; } } while(value<4.0); //これを抜けると発散と判断 switch(type){ //着色の色を設定する //繰返し回数そのままA case 0:g.setColor(countToColorA(count,color_base)); break; //繰返し回数そのままB case 1:g.setColor(countToColorB(count,color_base)); break; //繰返し回数の平方根 case 2:if(count>0)count=(int)Math.sqrt(count); g.setColor(countToColorB(count,color_base)); break; //発散時のZの偏角 case 3:if(count>0) count= (int)((z.arg()/(2*Math.PI)+0.5)*255); g.setColor(countToColorB(count,color_base)); break; default:break; } g.drawLine( X0+SIZE/2+x,Y0+SIZE/2-y,X0+SIZE/2+x,Y0+SIZE/2-y); } } g.setColor(getBackground()); g.fillRect(X0+SIZE+10,Y0+280,130,30); } //マンデルブロー図形を描画するメソッド public void drawMandel(){ Graphics g=getGraphics(); g.drawImage(img_mandel,X1,Y1,null); //crealとcimagに応じて白丸を描く g.setColor(Color.white); int x=(int)((creal+2.0)*MSIZE/2.5); int y=(int)((cimag-1.25)*MSIZE/2.5); g.drawOval(X1+x-2,Y1-y-2,4,4); } public void paint(Graphics g){ drawMandel(); } }
