I've got a GUI that generates a graphics image using the Mandelbrot set. I've implemented some zoom buttons, but I'd like to be able to change the centre of my GUI with a mouseclick (make mouse coordinates the new centre-point). It's proving to be quite difficult. Any suggestions? My attempt can be found at the moveGraph method.
Thanks in advance!
package assn4_12mgs;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class MandelBrot extends JFrame{
MandelPanel mp;
double xMax = 2.26;
double xMin = -2.24;
double yMax = 2.26;
double yMin = -2.24;
double yMove, xMove;
static double ESCAPE_MODULUS = 2.0;
static int MAX_ITERATIONS = 32;
public MandelBrot(){
super();
setLayout(new BorderLayout());
setTitle("Graham's Mandelbrot GUI");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600,700);
setResizable(false);
mp = new MandelPanel();
mp.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent evt) {
MoveGraph(evt);
}
});
JPanel panel = new JPanel(new FlowLayout());
JButton zoomIn = new JButton("+");
zoomIn.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent evt) {
ZoomIn(evt);
}
});
JButton zoomOut = new JButton("-");
zoomOut.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent evt) {
ZoomOut(evt);
}
});
JButton reset = new JButton("Reset");
reset.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent evt) {
reset(evt);
}
});
panel.add(reset, BorderLayout.WEST); ///How to change positioning?
panel.add(zoomOut, BorderLayout.EAST);
panel.add(zoomIn, BorderLayout.EAST);
add(panel, BorderLayout.SOUTH);
add(mp, BorderLayout.NORTH);
}
private void MoveGraph(MouseEvent evt){
int x = evt.getPoint().x;
int y = evt.getPoint().y;
xMove = x/100;
yMove = y/100;
mp.repaint();
}
private void ZoomIn(MouseEvent evt){
xMax /= 2;
xMin /= 2;
yMax /= 2;
yMin /= 2;
mp.repaint();
}
private void ZoomOut(MouseEvent evt){
xMax *= 2;
xMin *= 2;
yMax *= 2;
yMin *= 2;
mp.repaint();
}
private void reset(MouseEvent evt){
xMax = 2.26;
xMin = -2.24;
yMax = 2.26;
yMin = -2.24;
xMove = 0;
yMove = 0;
mp.repaint();
}
public class MandelPanel extends JPanel {
public MandelPanel() {
setPreferredSize(new Dimension(600,600));
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
// draw here
int row, col;
ComplexNumber c, z;
double xPos, yPos;
double modulus = 0;
boolean escaped = false;
int iterations = 0;
int desiredColour;
// Calculate the scale factor to go from pixels to actual units
int height = mp.getHeight(); // drawingZone is the JPanel drawing area
int width = mp.getWidth();
double xScale = (xMax - xMin) / width; // These are min and max values in actual
double yScale = (yMax - yMin) / height; // coordinates.
Graphics2D g2D = (Graphics2D)g;
BufferedImage pretty = new BufferedImage(width, height,
BufferedImage.TYPE_3BYTE_BGR);
// Iterate through the entire panel, pixel by pixel
for (row = 0; row < height; row++) {
// Calculate the actual y position
yPos = yMax - row * yScale;// - yMove
for (col = 0; col < width; col++) {
// Calculate the actual x position
xPos = xMin + col * xScale;// + xMove;
// Create the complex number for this position
c = new ComplexNumber(xPos, yPos);
z = new ComplexNumber(0, 0);
iterations = 0;
// Iterate the fractal equation z = z*z + c
// until z either escapes or the maximum number of iterations
// is reached
do {
z = (z.multiply(z)).add(c);
modulus = z.abs();
escaped = modulus > ESCAPE_MODULUS;
iterations++;
} while (iterations < MAX_ITERATIONS && !escaped);
// Set the colour according to what stopped the above loop
if (escaped) {
desiredColour = setEscapeColour(iterations);
} else {
desiredColour = setColour(modulus);
}
pretty.setRGB(col, row, desiredColour);
} // end for
} // end for
g2D.drawImage(pretty, null, 0, 0);
//yMove = 0;
//xMove = 0;
}
}
// Sets gray level for escape situation
private static int setEscapeColour(int numIterations) {
float grayLevel = 0.5F - (float) numIterations / MAX_ITERATIONS;
grayLevel = Math.max(grayLevel, 0.1F);
return new Color(grayLevel, grayLevel, grayLevel).getRGB();
} // end setEscapeColour
// Sets colour level for interior situation
// The algorithm used here is *totally* empirical!
private static int setColour(double modulus) {
float factor = (float) (modulus / ESCAPE_MODULUS);
float incr = (float) Math.log10(factor * 5.5);
float r = Math.min(Math.abs(10.0F * incr) * factor, 1.0F);
float g = Math.min(Math.abs(6.0F * incr) * factor, 1.0F);
float b = Math.min(Math.abs(0.5F * factor + incr), 1.0F);
return new Color(r, g, b).getRGB();
} // end setColour
public static void main(String args[]){
MandelBrot manBrot = new MandelBrot();
manBrot.setVisible(true);
}
}
We take a point on which a user has clicked as a center point for drawing, then calculate the window (half the distance up and down, left and right) around that point. See
** The Code**