/********************************************************
* Science of Complex System *
* *
* iida@fluid.mech.kogakuin.ac.jp *
********************************************************/
/*コンパイル: Usage: Javac Fractal.java */
/* 表示するためにはhtmlファイルが必要.以下のhtmlファイルを
作成し,実行する.Fractal.classがjavaのアプレット */
/*
Science of Complex System
*/
import java.awt.*;
import java.awt.image.*;
import java.applet.*;
import java.awt.event.*;
public class Fractal extends Applet
implements Runnable, MouseListener, MouseMotionListener {
int width ;
int height;
double scale = 2.1;
double kReal0 = -1.4;
double kImage0 = 0.9;
int iteration = 500;
Thread thread;
Image figure;
boolean flag;
public void init ( ) {
width = getSize().width;
height = getSize().height;
try {
iteration = Integer.parseInt(this.getParameter("iteration"));
}
catch (NumberFormatException e) { iteration = 500; }
this.addMouseMotionListener (this);
this.addMouseListener (this);
}
public void start ( ) {
width = getSize().width;
height = getSize().height;
thread = new Thread (this);
thread.start( );
}
// public synchronized void stop ( ) {
// if ((thread != null) && thread.isAlive()) thread.stop( );
// thread = null;
// }
public void paint (Graphics g) {
if (figure != null) g.drawImage (figure, 0, 0, null);
if (endX > startX && endY > startY && flag) {
//g.setColor (Color.yellow);
g.setXORMode(Color.yellow);
g.drawRect (startX, startY, endX - startX, endY - startY);
}
}
public void update (Graphics g) {
paint(g);
}
public synchronized void run ( ) {
Thread.currentThread().setPriority (Thread.MIN_PRIORITY);
byte[] pixels = new byte[width * height];
int index = 0;
int cycle = 0;
double kReal, kImage, zReal, zImage;
double zReal2, zImage2, zRealNew, zImageNew;
byte[] colorMap = new byte[256];
colorMap[0] = colorMap[1] = colorMap[2] = colorMap[3] = 0;
for (int i = 1; i < 64; i++) {
colorMap[i*4 ] = (byte) 255;
colorMap[i*4+1] = (byte) 255;
colorMap[i*4+2] = (byte) (i*4);
colorMap[i*4+3] = (byte) 0;
}
MemoryImageSource memImage = new MemoryImageSource (
width, height,
new IndexColorModel (8, 64, colorMap, 0, false, -1),
pixels, 0, width);
memImage.setAnimated (true);
figure = createImage (memImage);
/* repeat "iteration" times
* z := z*z + k where z = x + y*i and k = a + b*i;
*/
while (true) {
for (int y = 0; y < height; y++) {
kImage = kImage0 - (double)y/(double)height * scale;
for (int x = 0; x < width; x++) {
kReal = kReal0 + (double)x/(double)width * scale;
zReal = zImage = 0;
for (cycle = 0; cycle < iteration; cycle++ ) {
zReal2 = zReal * zReal;
zImage2 = zImage * zImage;
if ((zReal2 + zImage2) >= 4.0)
break;
zRealNew = zReal2 - zImage2 + kReal;
zImageNew = 2 * zReal * zImage + kImage;
zReal = zRealNew;
zImage = zImageNew;
}
if (cycle == iteration) { pixels[index] = 0; }
else { pixels[index] = (byte) (cycle % 64); }
memImage.newPixels(x, y, 1, 1);
index ++;
}
repaint ( );
}
//thread.suspend( );
index = 0;
}
}
//-------------------------------------------
int startX = 0;
int startY = 0;
int endX = -1;
int endY = -1;
//-------- Listeners -----
public void mouseDragged (MouseEvent e) {
e.consume( );
int x1 = e.getX( );
int y1 = e.getY( );
endX = x1;
endY = y1;
if ((endX > startX) || (endY > startY)) {
endX = x1;
endY = y1;
flag = true;
repaint( );
}
}
public void mouseMoved (MouseEvent e) {
e.consume( );
}
public void mousePressed (MouseEvent e) {
e.consume( );
int x1 = e.getX( );
int y1 = e.getY( );
startX = endX = x1;
startY = endY = y1;
}
public void mouseReleased (MouseEvent e) {
e.consume( );
int x1 = e.getX( );
int y1 = e.getY( );
//----------------------------
if (endX > startX || endY > startY) {
kReal0 += scale * (double)startX / (double)width;
kImage0 -= scale * (double) startY / (double)height;
scale = scale * (double)(endX - startX) / (double)width;
//thread.resume( );
flag = false;
repaint ( );
}
}
public void mouseEntered (MouseEvent e) {
e.consume( );
}
public void mouseExited (MouseEvent e) {
e.consume( );
}
public void mouseClicked (MouseEvent e) {
e.consume( );
}
}