Multi-threaded Julia set calculator

This commit is contained in:
Alberto Venturini 2017-09-09 19:57:41 +02:00
commit 1a0cd2fe69
4 changed files with 176 additions and 0 deletions

25
.gitignore vendored Normal file
View 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

View 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
View 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
View 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);
});
}
}