commit 1a0cd2fe699703eef00e4b675216ecb3fddbe08b Author: Alberto Venturini Date: Sat Sep 9 19:57:41 2017 +0200 Multi-threaded Julia set calculator diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89c8f39 --- /dev/null +++ b/.gitignore @@ -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 diff --git a/src/JuliaSetCalculator.java b/src/JuliaSetCalculator.java new file mode 100644 index 0000000..9910788 --- /dev/null +++ b/src/JuliaSetCalculator.java @@ -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; + } + + + +} diff --git a/src/JuliaSetPanel.java b/src/JuliaSetPanel.java new file mode 100644 index 0000000..e3627ae --- /dev/null +++ b/src/JuliaSetPanel.java @@ -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); + } + +} \ No newline at end of file diff --git a/src/MainClass.java b/src/MainClass.java new file mode 100644 index 0000000..97d3e88 --- /dev/null +++ b/src/MainClass.java @@ -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); + }); + } + +}