マンデルブロ集合

動作映像はこちらです。

下記のソースはこちらのソースを参考にして作りました。

ソースファイルは三つに分かれていて、三つともコンパイルしてから、
一番下のMandelFrame3だけ実行してください。

コンパイル javac MandelPanel2.java MandelPanel3.java MandelFrame3.java
実行 java MandelFrame3

MandelPanel2.java

import java.awt.*;
import java.awt.geom.*;

public class MandelPanel2 extends JPanel{

Graphics2D g2D;
int ox, oy;

public void paint(Graphics g){

g2D = (Graphics2D) g;
drawAxis();
}

public void drawAxis(){

Dimension size = getSize();
int w = size.width, h = size.height;

ox = 2*w/3;
oy = h/2;
AffineTransform T = new AffineTransform(1.0, 0.0, 0.0, -1.0, ox, oy);
g2D.transform(T);

}
}


MandelPanel3.java

import java.awt.*;

public class MandelPanel3 extends MandelPanel2{

double mag = 200.0;
double zx1 = 0.0;
double zy1 = 0.0;
double a = 1.0;

int zx2=416;
int zy2=250;

public void paint(Graphics g){

g2D = (Graphics2D) g;
drawAxis();

Point s;
double ux,uy,zx3,zy3;

zx3=(zx2-416)/(a*mag);
zy3=(250-zy2)/(a*mag);

s = function(0.0,0.0);

double zr,zi,z,p0,r;
int hx,hy;

for(uy=zy1+a*zy3-250/(a*mag);uy<=zy1+a*zy3+250/(a*mag);uy+=1/(a*mag)){
for(ux=zx1+a*zx3-416/(a*mag);ux<=zx1+a*zx3+208/(a*mag);ux+=1/(a*mag)){

s=function(ux,uy);

zr=0;zi=0;
for(int k=0;k<255;k++){
z=zr*zr-zi*zi+ux;
p0=2*zr*zi+uy;
r=z*z+p0*p0;
hx = (int)(s.x-a*a*zx3*mag);
hy = (int)(s.y-a*a*zy3*mag);
if(r>=4&&k<25){
g.setColor(new Color(0,k*10,255-k*10));
g.fillRect(hx,hy,1,1);
break;
}else if(r>=4&&k>=25&&k<=50){
g.setColor(new Color(k*5,255-k*5,0));
g.fillRect(hx,hy,1,1);
break;
}else if(r>=4&&k>50){
g.setColor(new Color(255-k,0,k));
g.fillRect(hx,hy,1,1);
break;
}else if(r<4&&k>=254){
g2D.setColor(new Color(0,0,0));
g2D.fillRect(hx,hy,1,1);
}
zr=z;zi=p0;
}
}
}

}

public Point function(double ux,double uy){

Point p = new Point();
p.x = (int)(ux*a*mag);
p.y = (int)(uy*a*mag);
return p;

}

}


MandelFrame3.java

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class MandelFrame3 extends JFrame implements ActionListener, MouseListener{

MandelPanel3 mandelpanel = new MandelPanel3();
JPanel bpanel = new JPanel();
JLabel blabel = new JLabel("一回ごとに画面をリセットしてください。");
JButton resetButton = new JButton("画面のリセット");
JPanel textpanel = new JPanel();
JLabel textlabel = new JLabel("倍率");
JRadioButton radio1 = new JRadioButton("2倍");
JRadioButton radio2 = new JRadioButton("10倍");
JRadioButton radio3 = new JRadioButton("100倍");
JRadioButton radio4 = new JRadioButton("1000倍");

MandelFrame3(String title){

super(title);
setSize(624,590);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);

mandelpanel.addMouseListener(this);
resetButton.addActionListener(this);
bpanel.add(blabel);
bpanel.add(resetButton);
textpanel.add(textlabel);

ButtonGroup group = new ButtonGroup();
group.add(radio1);
group.add(radio2);
group.add(radio3);
group.add(radio4);

textpanel.add(radio1);
textpanel.add(radio2);
textpanel.add(radio3);
textpanel.add(radio4);

setLayout(new BorderLayout());
add("North", bpanel);
add("Center", mandelpanel);
add("South", textpanel);
}

public static void main(String[] args){

MandelFrame3 mandelframe
= new MandelFrame3("マンデルブロ集合(倍率を選択して拡大したい場所をクリックしてください。)");
mandelframe.setVisible(true);
}

public void actionPerformed(ActionEvent evt){

Object source = evt.getSource();
if (source == resetButton){

mandelpanel.zx1 = 0.0;
mandelpanel.zy1 = 0.0;
mandelpanel.zx2 = 416;
mandelpanel.zy2 = 250;
mandelpanel.a = 1.0;

mandelpanel.repaint();

}
}

public void mouseClicked(MouseEvent e){

Point point = e.getPoint();
mandelpanel.zx2= point.x;
mandelpanel.zy2= point.y;
mandelpanel.zx1 = 0.0;
mandelpanel.zy1 = 0.0;

if (radio1.isSelected()){
mandelpanel.a = 2.0;
}else if (radio2.isSelected()){
mandelpanel.a = 10.0;
}else if (radio3.isSelected()){
mandelpanel.a = 100.0;
}else if (radio4.isSelected()){
mandelpanel.a = 1000.0;
}

mandelpanel.repaint();

}

public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}

}