import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class mdbasic extends JPanel implements MouseListener, MouseMotionListener, Runnable {
private final int MAX = 256; // #MaxIterations => infinity!
private final double SX = -2.025; // start value real
private final double SY = -1.125; // start value imaginary
private final double EX = 0.6; // end value real
private final double EY = 1.125; // end value imaginary
//Mandelbrot-set domain aspect ratio = 2.625/2.25 = 1.167
private static int x1, y1, xs, ys, xe, ye;
private static double xStart, yStart, xEnd, yEnd, xZoom, yZoom;
private static boolean actionOn, redrawCheck, ready2Run;
private static float XOverY; // (dynamic) Aspect ratio of Applet.
private Image iBoard;
private Graphics g1;
private Cursor c1, c2;
boolean running = false;
//list variables
private static int listIndex = 0; //for keeping track of next empty list index (adding/removing items from list)
private static int currentIndex = 0; //for keeping track of which list index current picture belongs to
private LinkedList positionStore = new LinkedList(); //linked list for storing position history
private Iterator it = positionStore.iterator();
public void start() { // all instances must be prepared, constructor
//ready2Run = false;
ready2Run = true;
addMouseListener(this);
addMouseMotionListener(this);
c1 = new Cursor(Cursor.WAIT_CURSOR);
c2 = new Cursor(Cursor.CROSSHAIR_CURSOR);
x1 = getSize().width;
y1 = getSize().height;
XOverY = (float)x1 / (float)y1;
iBoard = createImage(x1, y1);
g1 = iBoard.getGraphics();
actionOn = false;
redrawCheck = false;
makeAspectRatio();
xZoom = (xEnd - xStart) / (double)x1;
yZoom = (yEnd - yStart) / (double)y1;
mandelbrot();
//storing first set of coords for original picture
CoordinateHistory coord = new CoordinateHistory(xStart, yStart, xEnd, yEnd, xZoom, yZoom);
positionStore.add(listIndex, coord);
listIndex++;
}
public Image returnImage(){ //returns Image to GUI to obtain BufferedImage
return iBoard;
}
public void destroy() { // delete all instances
if (ready2Run) {
removeMouseListener(this);
removeMouseMotionListener(this);
iBoard = null;
g1 = null;
c1 = null;
c2 = null;
System.gc(); // garbage collection
}
}
// public void stop() {}
public void run()
{
paint(g1);
}
public void paint(Graphics g) {
if(!running){
start();
running = true;
update(g);
}else{
update(g);
}
}
public void update(Graphics g) {
g.drawImage(iBoard, 0, 0, this);
if (redrawCheck) {
g.setColor(Color.white);
if (xs < xe) {
if (ys < ye) g.drawRect(xs, ys, (xe - xs), (ye - ys));
else g.drawRect(xs, ye, (xe - xs), (ys - ye));
}
else {
if (ys < ye) g.drawRect(xe, ys, (xs - xe), (ye - ys));
else g.drawRect(xe, ye, (xs - xe), (ys - ye));
}
}
}
//function to remove past coords from list if new set has been made using cursor
public void removePastCoords()
{
int i = ((positionStore.size()) - listIndex);
for(int j = 0; j<i ; j++)
{
positionStore.removeLast();
}
}
private void mandelbrot() { // calculate all points
int x, y;
float h, b, alt = 0.0f;
actionOn = false;
setCursor(c1);
//showStatus("Computing Mandelbrot-Set ...");
for (x = 0; x < x1; x++) {
for (y = 0; y < y1; y++) {
h = pickColIndex(xStart + xZoom * (double)x, yStart + yZoom * (double)y); // color value
if (h != alt) {
b = 1.0f - h * h; // brightnes
g1.setColor(Color.getHSBColor(h, 0.8f, b));
alt = h;
}
g1.drawLine(x, y, x + 1, y);
}
}
//showStatus("Mandelbrot-Set completed: left-Drag mouse to zoom in area.");
setCursor(c2);
actionOn = true;
}
private void makeAspectRatio() { // reset start values
xStart = SX;
yStart = SY;
xEnd = EX;
yEnd = EY;
if ((float)((xEnd - xStart) / (yEnd - yStart)) != XOverY )
xStart = xEnd - (yEnd - yStart) * (double)XOverY;
}
private float pickColIndex(double xwert, double ywert) { // color value from 0.0 to 1.0 by iterations
double r = 0.0, i = 0.0, m = 0.0;
int j = 0;
while ((j < MAX) && (m < 4.0)) {
j++;
m = r * r - i * i;
i = 2.0 * r * i + ywert;
r = m + xwert;
}
return (float)j / (float) MAX;
}
public void mousePressed(MouseEvent e) {
e.consume();
if (actionOn) {
xs = e.getX();
ys = e.getY();
}
}
public void mouseReleased(MouseEvent e) {
int z, w;
e.consume();
if (actionOn) {
xe = e.getX();
ye = e.getY();
if (xs > xe) {
z = xs; xs = xe; xe = z;
}
if (ys > ye) {
z = ys; ys = ye; ye = z;
}
w = (xe - xs);
z = (ye - ys);
if ((w < 2) && (z < 2))
makeAspectRatio();
else {
if (((float)w > (float)z * XOverY)) ye = (int)((float)ys + (float)w / XOverY);
else xe = (int)((float)xs + (float)z * XOverY);
xEnd = xStart + xZoom * (double)xe;
yEnd = yStart + yZoom * (double)ye;
xStart += xZoom * (double)xs;
yStart += yZoom * (double)ys;
}
xZoom = (xEnd - xStart) / (double)x1;
yZoom = (yEnd - yStart) / (double)y1;
CoordinateHistory coord = new CoordinateHistory(xStart, yStart, xEnd, yEnd, xZoom, yZoom);
if(it.hasNext()){
removePastCoords();
}
positionStore.add(listIndex, coord);
listIndex++;
currentIndex++;
mandelbrot();
redrawCheck = false;
repaint();
}
}
public void mouseDragged(MouseEvent e) {
e.consume();
if (actionOn) {
xe = e.getX();
ye = e.getY();
redrawCheck = true;
repaint();
}
}
static final long serialVersionUID = 1L; // merely to avoid the (rather annoying!) warning.
}
Thats pretty much the whole class, minus a few irrelevent methods.
I was thinking of having the computations of the mandelbrot() method moved into a Thread class and having them output the points to a drawMandelBrot() method that uses g.drawLine but again, im not sure where to start and how to go about returning the values!