Multi-threaded Julia set calculator
This commit is contained in:
commit
1a0cd2fe69
4 changed files with 176 additions and 0 deletions
25
.gitignore
vendored
Normal file
25
.gitignore
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# Compiled class file
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# BlueJ files
|
||||||
|
*.ctxt
|
||||||
|
|
||||||
|
# Mobile Tools for Java (J2ME)
|
||||||
|
.mtj.tmp/
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.rar
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
|
||||||
|
*.iml
|
||||||
|
.idea
|
77
src/JuliaSetCalculator.java
Normal file
77
src/JuliaSetCalculator.java
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|
||||||
|
public class JuliaSetCalculator {
|
||||||
|
private int width;
|
||||||
|
private int height;
|
||||||
|
private int[][] iterations;
|
||||||
|
|
||||||
|
public JuliaSetCalculator(final int width, final int height) {
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
iterations = new int[width][height];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[][] calculate(
|
||||||
|
final int maxIterations,
|
||||||
|
final double zoom,
|
||||||
|
final double cx,
|
||||||
|
final double cy,
|
||||||
|
final double moveX,
|
||||||
|
final double moveY) {
|
||||||
|
|
||||||
|
class JuliaTask implements Runnable {
|
||||||
|
|
||||||
|
private int x;
|
||||||
|
|
||||||
|
JuliaTask(int x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
double zx, zy;
|
||||||
|
for(int y = 0; y < height; y++) {
|
||||||
|
zx = 1.5 * (x - width / 2) / (0.5 * zoom * width) + moveX;
|
||||||
|
zy = (y - height / 2) / (0.5 * zoom * height) + moveY;
|
||||||
|
int i = maxIterations;
|
||||||
|
while (zx * zx + zy * zy < 4 && i > 0) {
|
||||||
|
double tmp = zx * zx - zy * zy + cx;
|
||||||
|
zy = 2.0 * zx * zy + cy;
|
||||||
|
zx = tmp;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
iterations[x][y] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
ExecutorService executorService = Executors.newWorkStealingPool(8);
|
||||||
|
for(int x = 0; x < width; x++) {
|
||||||
|
JuliaTask task = new JuliaTask(x);
|
||||||
|
executorService.submit(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
executorService.shutdown();
|
||||||
|
|
||||||
|
try {
|
||||||
|
executorService.awaitTermination(5, TimeUnit.SECONDS);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
System.out.println(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
System.out.println(endTime - startTime);
|
||||||
|
|
||||||
|
return iterations;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
49
src/JuliaSetPanel.java
Normal file
49
src/JuliaSetPanel.java
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
public class JuliaSetPanel extends JPanel {
|
||||||
|
private static int maxIter = 1000;
|
||||||
|
private static double zoom = 1;
|
||||||
|
private double cY, cX;
|
||||||
|
|
||||||
|
private JuliaSetCalculator juliaSetCalculator;
|
||||||
|
|
||||||
|
public JuliaSetPanel(final JuliaSetCalculator juliaSetCalculator, final int width, final int height) {
|
||||||
|
this.juliaSetCalculator = juliaSetCalculator;
|
||||||
|
setPreferredSize(new Dimension(1200, 800));
|
||||||
|
setBackground(Color.white);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawJuliaSet(Graphics2D g) {
|
||||||
|
int width = getWidth();
|
||||||
|
int height = getHeight();
|
||||||
|
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||||
|
|
||||||
|
cX = -0.7;
|
||||||
|
cY = 0.27015;
|
||||||
|
double moveX = 0, moveY = 0;
|
||||||
|
|
||||||
|
int[][] iterations = juliaSetCalculator.calculate(maxIter, zoom, cX, cY, moveX, moveY);
|
||||||
|
|
||||||
|
for(int x = 0; x < width; x++) {
|
||||||
|
for(int y = 0; y < height; y++) {
|
||||||
|
float i = iterations[x][y];
|
||||||
|
int color = Color.HSBtoRGB(((maxIter / i) + 0.5f) % 1, 1, i > 0 ? 1 : 0);
|
||||||
|
image.setRGB(x, y, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g.drawImage(image, 0, 0, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintComponent(Graphics gg) {
|
||||||
|
super.paintComponent(gg);
|
||||||
|
Graphics2D g = (Graphics2D) gg;
|
||||||
|
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||||
|
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
drawJuliaSet(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
25
src/MainClass.java
Normal file
25
src/MainClass.java
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
public class MainClass {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
int width = 1200;
|
||||||
|
int height = 800;
|
||||||
|
JuliaSetCalculator juliaSetCalculator = new JuliaSetCalculator(width, height);
|
||||||
|
JuliaSetPanel juliaSetPanel = new JuliaSetPanel(juliaSetCalculator, width, height);
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
JFrame f = new JFrame();
|
||||||
|
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
f.setTitle("Julia Set");
|
||||||
|
f.setResizable(false);
|
||||||
|
f.add(juliaSetPanel, BorderLayout.CENTER);
|
||||||
|
f.pack();
|
||||||
|
f.setLocationRelativeTo(null);
|
||||||
|
f.setVisible(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue