Multi-threaded Julia set calculator
This commit is contained in:
		
						commit
						1a0cd2fe69
					
				
					 4 changed files with 176 additions and 0 deletions
				
			
		
							
								
								
									
										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