import java.applet.*; import java.awt.*; import java.awt.image.*; import java.awt.event.*; import java.text.*; import java.lang.*; import java.util.*; //--------------------------------------------------------// // フラクタル(マンデルブロ集合・ジュリア集合) // //--------------------------------------------------------// // クラス一覧 // class fractal メイン // class ViewPanel 画面部分 // class ControlPanel コントロールパネル // class Slider スライダーコントロール // class FractalMJ フラクタル計算 //--------------------------------------------------------// //--------------------------------------------------------// // メイン public class fractal extends Applet{ ViewPanel view; ControlPanel cont; Slider z1; Slider z2; double a=0.0,b=0.0; // 初期パラメータ //--------------------------------------------------------// public void init(){ setLayout(new BorderLayout()); z1=new Slider(50,getSize().height/4,0.0,0.5,a,"Real"); z2=new Slider(50,getSize().height/4,0.0,0.5,b,"Imag"); view=new ViewPanel(z1,z2); cont=new ControlPanel(view,z1,z2); add("Center",view); add("East",cont); } //--------------------------------------------------------// public void destroy(){ remove(z1); remove(z2); remove(view); remove(cont); } } //--------------------------------------------------------// // 画面部分 class ViewPanel extends Panel implements MouseListener,KeyListener{ FractalMJ frac; Slider z1; Slider z2; Image img; int nmax=1000000; // 画面ピクセル数の上限 int color[]=new int[nmax]; // 画面表示の色 int prex=0,prey=0; int fx,fy; // 画面サイズ int sw=0; // 0 - マンデルブロ集合, 1 - ジュリア集合 Color backColor,lineColor; // 背景色・線色 boolean paintsw=true; //--------------------------------------------------------// public ViewPanel(Slider z1,Slider z2){ this.z1=z1; this.z2=z2; backColor=Color.blue; lineColor=Color.white; setBackground(backColor); addMouseListener(this); addKeyListener(this); } //--------------------------------------------------------// public void mouseClicked(MouseEvent e){ } //--------------------------------------------------------// public void mousePressed(MouseEvent e){ prex=e.getX(); prey=e.getY(); drawCorner(prex,prey); e.consume(); } //--------------------------------------------------------// public void mouseReleased(MouseEvent e){ int x=e.getX(); int y=e.getY(); e.consume(); frac.setSize(prex,prey,x,y); paintsw=true; repaint(); prex=0; prey=0; } //--------------------------------------------------------// public void mouseEntered(MouseEvent e){ } //--------------------------------------------------------// public void mouseExited(MouseEvent e){ } //--------------------------------------------------------// public void keyPressed(KeyEvent e){ } //--------------------------------------------------------// public void keyReleased(KeyEvent e){ } //--------------------------------------------------------// public void keyTyped(KeyEvent e){ char keyin; keyin=(char)e.getKeyChar(); switch(keyin){ case '1': reset(); break; case '5': setSwitch(1-sw); break; case 'r': reset(); break; case 'c': setSwitch(1-sw); break; } } //--------------------------------------------------------// public void reset(){ frac.initialize(); paintsw=true; repaint(); } //--------------------------------------------------------// public void setSwitch(int sw){ this.sw=sw; reset(); } //--------------------------------------------------------// void drawCorner(int x,int y) { Graphics g=getGraphics(); int ds=4; g.setColor(lineColor); g.drawLine(x-ds,y,x+ds,y); g.drawLine(x,y-ds,x,y+ds); } //--------------------------------------------------------// public void update(Graphics g) { if(paintsw){ g.setColor(lineColor); g.drawString("Now calculating...",10,fx/2); frac.setParameter(z1.value,z2.value); if(sw==0) frac.calculateMandelbrot2(color); else frac.calculateJulia2(color); img=createImage(new MemoryImageSource(fx,fy,color,0,fx)); paintsw=false; } g.drawImage(img,0,0,this); } //--------------------------------------------------------// public void paint(Graphics g) { if(paintsw){ fx=Math.min(getSize().width,getSize().height); if(fx<100) fx=100; else if(fx>1000) fx=1000; fy=fx; frac=new FractalMJ(fx,fy); g.setColor(lineColor); g.drawString("Now calculating...",10,fx/2); frac.setParameter(z1.value,z2.value); if(sw==0) frac.calculateMandelbrot2(color); else frac.calculateJulia2(color); img=createImage(new MemoryImageSource(fx,fy,color,0,fx)); paintsw=false; } g.drawImage(img,0,0,this); } } //--------------------------------------------------------// // コントロールパネル class ControlPanel extends Panel implements ActionListener,ItemListener{ ViewPanel view; Slider z1; Slider z2; Choice fracmenu=new Choice(); Button reset=new Button("Reset"); //--------------------------------------------------------// public ControlPanel(ViewPanel view,Slider z1,Slider z2){ this.view=view; setLayout(new GridLayout(4,1)); this.z1=z1; this.z2=z2; add(z1); add(z2); fracmenu.addItem("Mandelbrot"); fracmenu.addItem("Julia"); fracmenu.select(0); fracmenu.addItemListener(this); add(fracmenu); reset.addActionListener(this); add(reset); } //--------------------------------------------------------// public void actionPerformed(ActionEvent e){ // 基準の設定 if(e.getSource().equals(reset)){ view.reset(); } } //--------------------------------------------------------// public void itemStateChanged(ItemEvent e){ // 表示変更 String TypeString=null; int sw=0; if(e.getSource() instanceof Choice){ TypeString=(String)e.getItem(); if(TypeString.equals("Mandelbrot")) sw=0; else if(TypeString.equals("Julia")) sw=1; view.setSwitch(sw); } } } //--------------------------------------------------------// // スライダーコントロール class Slider extends Panel implements MouseListener,MouseMotionListener{ int fy; // 表示サイズ double max,min; // 最大値・最小値 double value; // 値 double coef; // 値の変換係数 int slw=4; // スライダーの幅 int xmin,xwidth; // スライダー表示位置・長さ int bead=10; // ビーズの大きさ int beadx,bx0,by0; // ビーズの位置 int prex,prey; // マウス位置 boolean move=false; // スライダーの移動 String title; Slider(int fx,int fy,double min,double max,double value ,String title){ xmin=(int)(0.2*fx); xwidth=fx; this.fy=fy; this.min=min; this.max=max; this.value=value; this.title=title; coef=xwidth/(max-min); beadx=xmin+(int)(coef*(value-min)); bx0=beadx-bead/2; by0=(fy-bead)/2; addMouseListener(this); addMouseMotionListener(this); } //--------------------------------------------------------// public void mouseClicked(MouseEvent e){ } //--------------------------------------------------------// public void mousePressed(MouseEvent e){ prex=e.getX(); prey=e.getY(); e.consume(); if(bx0<=prex & prex<=bx0+bead){ if(by0<=prey & prey<=by0+bead){ move=true; } } } //--------------------------------------------------------// public void mouseReleased(MouseEvent e){ move=false; } //--------------------------------------------------------// public void mouseEntered(MouseEvent e){ } //--------------------------------------------------------// public void mouseExited(MouseEvent e){ } //--------------------------------------------------------// public void mouseDragged(MouseEvent e){ int x=e.getX(); int y=e.getY(); if(move){ beadx+=x-prex; if(beadxxmin+xwidth) beadx=xmin+xwidth; value=min+(beadx-xmin)/coef; bx0=beadx-bead/2; by0=(fy-bead)/2; repaint(); } prex=x; prey=y; e.consume(); } //--------------------------------------------------------// public void mouseMoved(MouseEvent e){ } //--------------------------------------------------------// public void paint(Graphics g){ int texth,textwmin,textwmax,textwval; String mins,maxs,values; FontMetrics fm=g.getFontMetrics(); texth=fm.getHeight(); mins=""+(float)min; maxs=""+(float)max; values=title+": "+(float)value; textwmin=fm.stringWidth(mins); textwmax=fm.stringWidth(maxs); textwval=fm.stringWidth(values); g.drawRect(xmin,(fy-slw)/2,xwidth,slw); g.fillRect(bx0,by0,bead,bead); g.drawString(mins,xmin-textwmin/2,by0+bead+texth); g.drawString(maxs,xmin+xwidth-textwmin/2,by0+bead+texth); g.drawString(values,xmin/2,by0-bead); } } //--------------------------------------------------------// // フラクタル計算 class FractalMJ{ int itmax=100; // 計算反復回数の上限 int fx,fy; // 画面サイズ double coefx,coefy; // 座標変換係数 double x0,y0; // 画面中心座標 double dx,dy; // 画面表示領域サイズ double alpha,beta; // パラメータ Image img; //--------------------------------------------------------// FractalMJ(int fx,int fy){ this.fx=fx; this.fy=fy; initialize(); } //--------------------------------------------------------// void initialize(){ // 初期化 dx=4.0; dy=4.0; x0=0.0; y0=0.0; coefx=dx/fx; coefy=dy/fy; } //--------------------------------------------------------// void setSize(int x1,int y1,int x2,int y2){ // 描画領域設定 double coefdx,coefdy,coefd; x0-=0.5*(dx-coefx*(x1+x2)); y0+=0.5*(dy-coefy*(y1+y2)); coefdx=(double)(Math.abs(x1-x2))/fx; coefdy=(double)(Math.abs(y1-y2))/fy; coefd=Math.max(coefdx,coefdy); if(coefd==0.0) coefd=1.0/Math.max(fx,fy); dx=coefd*dx; dy=coefd*dy; coefx=dx/fx; coefy=dy/fy; } //--------------------------------------------------------// void setParameter(double alpha,double beta){ // パラメータ設定 this.alpha=alpha; this.beta=beta; } //--------------------------------------------------------// int MJfunc2(double z1,double z2,double c1,double c2,int itermax){ // Zk=Zk-1^2+c の反復回数 int i; double mag,z11,z22,z12; for(i=0;i4.0) return i; z12=z1*z2; z1=z11-z22+c1; z2=z12+z12+c2; } return itermax; } //--------------------------------------------------------// int colorSet(int value,int vmax){ // 色の設定 int vm2,vm4,cr=0,cg=0,cb=0; float coef=1020f/vmax; vm2=vmax/2; vm4=vmax/4; if(value<=0){ cb=255; } else if(value