aboutsummaryrefslogtreecommitdiff
path: root/Week15 Mandelbrot/src/com/camilstaps/mandelbrot/DrawView.java
diff options
context:
space:
mode:
authorCamil Staps2015-06-04 22:33:05 +0200
committerCamil Staps2015-06-04 22:44:48 +0200
commit6fd61db17fc695355d0c604507e7a86b0e84eba2 (patch)
treea3e582dba961b59945b12f8776ad115f52bdce7d /Week15 Mandelbrot/src/com/camilstaps/mandelbrot/DrawView.java
parentStart 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.java167
1 files changed, 167 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..4d73434
--- /dev/null
+++ b/Week15 Mandelbrot/src/com/camilstaps/mandelbrot/DrawView.java
@@ -0,0 +1,167 @@
+/*
+ * 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.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;
+ }
+ }
+
+}