diff options
author | Camil Staps | 2015-06-04 22:33:05 +0200 |
---|---|---|
committer | Camil Staps | 2015-06-04 22:33:30 +0200 |
commit | 85751141b5705dba503b507ab34cc4ee734a9e6a (patch) | |
tree | 03fd9ccca1cc3af668bd2ee2b3510ba32268cb33 /Week15 Mandelbrot/src/com/camilstaps/mandelbrot/DrawView.java | |
parent | Start week15 (diff) |
Started own version
Diffstat (limited to 'Week15 Mandelbrot/src/com/camilstaps/mandelbrot/DrawView.java')
-rw-r--r-- | Week15 Mandelbrot/src/com/camilstaps/mandelbrot/DrawView.java | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/Week15 Mandelbrot/src/com/camilstaps/mandelbrot/DrawView.java b/Week15 Mandelbrot/src/com/camilstaps/mandelbrot/DrawView.java new file mode 100644 index 0000000..16500f5 --- /dev/null +++ b/Week15 Mandelbrot/src/com/camilstaps/mandelbrot/DrawView.java @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2015 Camil Staps + */ +package com.camilstaps.mandelbrot; + +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.image.BufferedImage; +import java.awt.image.WritableRaster; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Observable; +import java.util.Observer; +import javax.swing.JPanel; +import javax.swing.SwingWorker; + +/** + * + * @author camilstaps + */ +public class DrawView extends JPanel implements Observer { + + private final FractalModel fractalModel; + + private final BufferedImage image; + private final WritableRaster raster; + private final int width, height; + private static final int DEFAULT_WIDTH = 500, DEFAULT_HEIGHT = 500; + + private int pixelCounter; + private static final int COUNTER_MAX = 1000; + + private static final int REPETITIONS_MAX = 150; + + public DrawView(FractalModel fractalModel) { + this.fractalModel = fractalModel; + fractalModel.addObserver(this); + + width = DEFAULT_WIDTH; + height = DEFAULT_HEIGHT; + + image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + raster = image.getRaster(); + + setPreferredSize(new Dimension(width, height)); + + update(fractalModel, null); + } + + @Override + public int getWidth() { + return width; + } + + @Override + public int getHeight() { + return height; + } + + @Override + public void update(Observable o, Object o1) { + Updater task = new Updater(); + task.execute(); + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + g.drawImage(image, 0, 0, null); + } + + public void setPixel(int x, int y, int[] rgb) { + raster.setPixel(x, y, rgb); + pixelCounter++; + if (pixelCounter > COUNTER_MAX) { + pixelCounter = 0; + repaint(); + } + } + + protected double getRealX(int pixel_x) { + return ((double) pixel_x * (fractalModel.getEndX() - fractalModel.getStartX()) / width) + fractalModel.getStartX(); + } + + protected double getRealY(int pixel_y) { + return ((double) pixel_y * (fractalModel.getEndY() - fractalModel.getStartY()) / height) + fractalModel.getStartY(); + } + + protected class Updater extends SwingWorker<Map<Point,Double>, Map<Point,Double>> { + private boolean doneProcessing = true; + + @Override + protected Map<Point, Double> doInBackground() throws Exception { + Map<Point,Double> results = new HashMap<>(); + + for (int repetitions = 1; repetitions < REPETITIONS_MAX; repetitions++) { + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + // Convert mandel number to some number in [0,pi] to let the colourise below work nicely + double mandel = ((double) fractalModel.getMandelNumber(getRealX(x), getRealY(y), repetitions) * Math.PI) / repetitions; + + //System.err.println("x,y : " + getRealX(x) + "," + getRealY(y) + "; " + mandel); + + Point p = new Point(x, y); + results.put(p, mandel); + } + } + + System.out.println("Rep " + repetitions); + + if (doneProcessing) { + doneProcessing = false; + publish(results); + } + setProgress(repetitions * 100 / REPETITIONS_MAX); + } + + return results; + } + + @Override + protected synchronized void process(List<Map<Point,Double>> results) { + for (Map<Point,Double> resultMap : results) { + for (Entry<Point,Double> result : resultMap.entrySet()) { + double value = result.getValue(); + + // Different mandel numbers have different colours +// int[] rgb = { +// (int) (30 + 220 * Math.sin(value)), +// (int) (30 + 220 * Math.sin(value + 2 * Math.PI / 3)), +// (int) (30 + 220 * Math.sin(value + 4 * Math.PI / 3))}; + // This is a grayscale version: + int[] rgb = {(int) (255 * value), (int) (255 * value), (int) (255 * value)}; + + setPixel(result.getKey().x, result.getKey().y, rgb); + } + } + doneProcessing = true; + } + } + + protected class Point { + int x, y; + + public Point(int x, int y) { + this.x = x; + this.y = y; + } + + @Override + public boolean equals(Object another) { + if (another == null || another.getClass() != Point.class) { + return false; + } + Point that = (Point) another; + return that.x == x && that.y == y; + } + + @Override + public int hashCode() { + return (x << 8) | y; + } + } + +} |