Skip to content

Instantly share code, notes, and snippets.

@quoll
Created May 22, 2012 15:01
Show Gist options
  • Save quoll/2769622 to your computer and use it in GitHub Desktop.
Save quoll/2769622 to your computer and use it in GitHub Desktop.
Java Mandelbrot test
package test;
public class Complex {
public final double real;
public final double imaginary;
public Complex(double r, double i) {
real = r;
imaginary = i;
}
public final double abs() {
return Math.sqrt(real * real + imaginary * imaginary);
}
public final double absSquared() {
return real * real + imaginary * imaginary;
}
public final Complex plus(Complex that) {
return new Complex(real + that.real, imaginary + that.imaginary);
}
public final Complex times(Complex that) {
return new Complex(real * that.real - imaginary * that.imaginary, real * that.imaginary + imaginary * that.real);
}
public final Complex minus(Complex that) {
return new Complex(real - that.real, imaginary - that.imaginary);
}
public final Complex divide(Complex that) {
double denom = that.real * that.real + that.imaginary * that.imaginary;
return new Complex((real * that.real + imaginary * that.imaginary) / denom,
(imaginary * that.real - real * that.imaginary) / denom);
}
public final Complex plus(double that) {
return new Complex(real + that, imaginary);
}
public final Complex times(double that) {
return new Complex(real * that, imaginary * that);
}
public final Complex minus(double that) {
return new Complex(real - that, imaginary);
}
public final Complex divide(double that) {
return new Complex(real / that, imaginary / that);
}
}
package gr;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Point;
import java.awt.BasicStroke;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
public abstract class Drawing extends JPanel {
private static final String DEFAULT_NAME = "Main";
private static final int DEFAULT_WIDTH = 500;
private static final int DEFAULT_HEIGHT = 500;
private JFrame frame;
private String name;
private Color background;
private KeyListener kl;
private int currentX = 0;
private int currentY = 0;
public void run() {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() { startWindow(); }
});
}
protected Drawing() {
this(DEFAULT_NAME, DEFAULT_WIDTH, DEFAULT_HEIGHT, null);
}
protected Drawing(String name) {
this(name, DEFAULT_WIDTH, DEFAULT_HEIGHT, null);
}
protected Drawing(int width, int height) {
this(DEFAULT_NAME, width, height, null);
}
protected Drawing(String name, int width, int height) {
this(name, width, height, null);
}
protected Drawing(Color background) {
this(DEFAULT_NAME, DEFAULT_WIDTH, DEFAULT_HEIGHT, background);
}
protected Drawing(String name, Color background) {
this(name, DEFAULT_WIDTH, DEFAULT_HEIGHT, background);
}
protected Drawing(int width, int height, Color background) {
this(DEFAULT_NAME, width, height, background);
}
protected Drawing(String name, int width, int height, Color background) {
this.name = name;
setPreferredSize(new Dimension(width, height));
this.background = background;
}
protected void startWindow() {
frame = new JFrame(name);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(this);
frame.pack();
frame.setBackground(background);
kl = new KL();
frame.addKeyListener(kl);
frame.setVisible(true);
}
public void addKeyListener(KeyListener l) {
frame.removeKeyListener(kl);
frame.addKeyListener(l);
}
public Drawing setBG(Color c) {
background = c;
if (frame != null) frame.setBackground(c);
return this;
}
public void setPos(int x, int y) {
currentX = x;
currentY = y;
}
public void plot(Graphics g, int x, int y) {
currentX = x;
currentY = y;
g.fillRect(x, y, 1, 1);
}
public void plot(Graphics g, int x, int y, Color c) {
Color lc = g.getColor();
g.setColor(c);
plot(g, x, y);
g.setColor(lc);
}
public void plot(Graphics g, double x, double y) {
plot(g, (int)x, (int)y);
}
public void plot(Graphics g, double x, double y, Color c) {
plot(g, (int)x, (int)y, c);
}
public void lineto(Graphics g, int x, int y) {
g.drawLine(currentX, currentY, x, y);
currentX = x;
currentY = y;
}
public void lineto(Graphics g, int x, int y, Color c) {
Color lc = g.getColor();
g.setColor(c);
lineto(g, x, y);
g.setColor(lc);
}
public void lineto(Graphics g, double x, double y) {
lineto(g, (int)x, (int)y);
}
public void lineto(Graphics g, double x, double y, Color c) {
lineto(g, (int)x, (int)y, c);
}
public Point getCenter() {
return new Point(getWidth() / 2, getHeight() / 2);
}
private class KL implements KeyListener {
public void keyPressed(KeyEvent e) {
if (e.getKeyChar() == 'q') System.exit(0);
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
}
package test;
import gr.Drawing;
import java.awt.*;
import java.awt.event.KeyEvent;
public class Mand extends Drawing {
public static void main(String[] args) {
new Mand(INITIAL_WIDTH, INITIAL_HEIGHT).setBG(Color.WHITE).run();
}
private static final int R = 100;
private static final double TAU = 2 * Math.PI;
private static final double INC = TAU / 100.0;
private static final double INITIAL_MIN_X = -2.0;
private static final double INITIAL_MAX_X = 1.0;
private static final double INITIAL_MIN_Y = -1.0;
private static final double INITIAL_MAX_Y = 1.0;
private double minX = INITIAL_MIN_X;
private double maxX = INITIAL_MAX_X;
private double minY = INITIAL_MIN_Y;
private double maxY = INITIAL_MAX_Y;
private static final int INITIAL_WIDTH = 300;
private static final int INITIAL_HEIGHT = 200;
private static int limit = 1000;
private double mathWidth = maxX - minX;
private double mathHeight = maxY - minY;
private int gWidth = 0;
private int gHeight = 0;
public Mand(int w, int h) {
super(w, h);
}
public void paint(Graphics g) {
setExtents();
System.out.println("Rendering: " + gWidth + "x" + gHeight);
long time = System.currentTimeMillis();
for (int x = 0; x < gWidth; x++) {
for (int y = 0; y < gHeight; y++) {
g.setColor(mandelbrotColor(coord2Math(x, y)));
plot(g, x, y);
}
}
System.out.println("Render: " + (System.currentTimeMillis() - time) + "ms");
}
private final void setExtents() {
gWidth = getWidth();
gHeight = getHeight();
mathWidth = maxX - minX;
mathHeight = maxY - minY;
}
private final Complex coord2Math(int x, int y) {
double mx = x * mathWidth / gWidth + minX;
double my = maxY - y * mathHeight / gHeight;
return new Complex(mx, my);
}
private static final int scaled(int count) {
return (int)(Math.log(count + 1) * 37);
}
private static final Color mandelbrotColor(Complex c) {
Complex z = new Complex(0, 0);
int count = 0;
do {
z = z.times(z).plus(c);
if (count++ >= limit) return Color.blue;
} while (z.absSquared() < 4.0);
return new Color(scaled(count), 0, 0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment