performace not very good but it is working
This commit is contained in:
parent
d911477ad7
commit
1eaf63e2fe
|
@ -0,0 +1,186 @@
|
|||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class MandelbrotVisualizer extends JPanel implements MouseWheelListener, MouseMotionListener, MouseListener {
|
||||
private static final int WIDTH = 800;
|
||||
private static final int HEIGHT = 800;
|
||||
private BufferedImage image;
|
||||
private double zoom = 200;
|
||||
private double offsetX = 0;
|
||||
private double offsetY = 0;
|
||||
private int lastX, lastY;
|
||||
private ExecutorService executor;
|
||||
|
||||
public MandelbrotVisualizer() {
|
||||
image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
|
||||
addMouseWheelListener(this);
|
||||
addMouseMotionListener(this);
|
||||
addMouseListener(this);
|
||||
executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||
renderMandelbrot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the Mandelbrot set in the window.
|
||||
*/
|
||||
private void renderMandelbrot() {
|
||||
// Shutdown the existing executor and create a new one with the number of available processors.
|
||||
executor.shutdownNow();
|
||||
executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||
|
||||
// Iterate through each pixel in the image.
|
||||
for (int x = 0; x < WIDTH; x++) {
|
||||
final int fx = x;
|
||||
|
||||
// Submit a task to the executor for each row in the image.
|
||||
executor.submit(() -> {
|
||||
for (int y = 0; y < HEIGHT; y++) {
|
||||
double zx = (fx - WIDTH / 2) / zoom + offsetX;
|
||||
double zy = (y - HEIGHT / 2) / zoom + offsetY;
|
||||
|
||||
// Calculate the complex number c.
|
||||
float c = mandelbrot(zx, zy);
|
||||
|
||||
// Determine the color for the pixel based on the value of c.
|
||||
int color = Color.HSBtoRGB(0.7f + 10 * c, 0.7f, c > 0 ? 1 : 0);
|
||||
|
||||
// Set the color of the pixel in the image.
|
||||
image.setRGB(fx, y, color);
|
||||
}
|
||||
|
||||
// Repaint the window to display the updated image.
|
||||
repaint();
|
||||
});
|
||||
}
|
||||
|
||||
// Shutdown the executor and wait for all tasks to complete.
|
||||
/**
|
||||
* Attempts to shut down the executor and wait for all tasks to complete. If an InterruptedException occurs, print the stack trace.
|
||||
*/
|
||||
try {
|
||||
executor.shutdown();
|
||||
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the number of iterations for a given point in the Mandelbrot set.
|
||||
* @param zx the real part of the complex number
|
||||
* @param zy the imaginary part of the complex number
|
||||
* @return the number of iterations, scaled between 0 and 1
|
||||
*/
|
||||
private float mandelbrot(double zx, double zy) {
|
||||
double x = 0, y = 0;
|
||||
int maxIter = 1000;
|
||||
int iter;
|
||||
for (iter = 0; iter < maxIter && x * x + y * y < 4; iter++) {
|
||||
double temp = x * x - y * y + zx;
|
||||
y = 2 * x * y + zy;
|
||||
x = temp;
|
||||
}
|
||||
return iter < maxIter ? (float) iter / maxIter : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the Mandelbrot set in the given Graphics object.
|
||||
* @param g the Graphics object to paint onto
|
||||
*/
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
g.drawImage(image, 0, 0, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the mouse wheel event. Zooms in or out based on the scroll direction, and pans the view accordingly. Then repaints the window.
|
||||
* @param e the MouseWheelEvent that triggered this method call
|
||||
*/
|
||||
@Override
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
int notches = e.getWheelRotation();
|
||||
double mouseX = (e.getX() - WIDTH / 2.0) / zoom + offsetX;
|
||||
double mouseY = (e.getY() - HEIGHT / 2.0) / zoom + offsetY;
|
||||
|
||||
if (notches < 0) {
|
||||
zoom *= 1.1;
|
||||
} else {
|
||||
zoom /= 1.1;
|
||||
}
|
||||
|
||||
offsetX = mouseX - (e.getX() - WIDTH / 2.0) / zoom;
|
||||
offsetY = mouseY - (e.getY() - HEIGHT / 2.0) / zoom;
|
||||
|
||||
renderMandelbrot();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles the mouse dragged event. Updates the offset values for zooming and panning, then repaints the window.
|
||||
*/
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
int dx = e.getX() - lastX;
|
||||
int dy = e.getY() - lastY;
|
||||
|
||||
offsetX -= dx / zoom;
|
||||
offsetY -= dy / zoom;
|
||||
|
||||
lastX = e.getX();
|
||||
lastY = e.getY();
|
||||
|
||||
renderMandelbrot();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
lastX = e.getX();
|
||||
lastY = e.getY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {}
|
||||
|
||||
/**
|
||||
* The main method that initializes and displays the Mandelbrot visualizer window.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// Create a JFrame to hold the MandelbrotVisualizer panel.
|
||||
JFrame frame = new JFrame("Mandelbrot Visualizer");
|
||||
|
||||
// Instantiate the MandelbrotVisualizer panel.
|
||||
MandelbrotVisualizer panel = new MandelbrotVisualizer();
|
||||
|
||||
// Add the panel to the frame.
|
||||
frame.add(panel);
|
||||
|
||||
// Set the size of the frame.
|
||||
frame.setSize(WIDTH, HEIGHT);
|
||||
|
||||
// Configure the frame's default close operation and center it on the screen.
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.setLocationRelativeTo(null);
|
||||
|
||||
// Make the frame visible.
|
||||
frame.setVisible(true);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue