Paste: java mandelbrot

Author: slava
Mode: java
Date: Thu, 24 Sep 2009 07:33:29
Plain Text |
import java.io.*;

public class Mandel
{
	static class Complex
	{
		final double real, imag;

		Complex(double r, double i)
		{
			real = r;
			imag = i;
		}

		Complex add(Complex y)
		{
			return new Complex(real + y.real,imag + y.imag);
		}

		Complex mul(Complex y)
		{
			return new Complex(real * y.real - imag * y.imag,
				real * y.imag + imag * y.real);
		}

		double absq()
		{
			return real * real + imag * imag;
		}
	}

	static class HSV
	{
		double h, s, v;

		HSV(double h, double s, double v)
		{
			this.h = h;
			this.s = s;
			this.v = v;
		}

		int hi()
		{
			return (int)Math.floor(h / 60) % 6;
		}

		double f()
		{
			return h / 60 - hi();
		}

		double p()
		{
			return (1 - s) * v;
		}

		double q()
		{
			return (1 - f() * s) * v;
		}

		double t()
		{
			return (1 - ((1 - f()) * s)) * v;
		}

		byte[] makeRGB(double r, double g, double b)
		{
			byte[] ret = new byte[3];
			ret[0] = (byte)(r * 255);
			ret[1] = (byte)(g * 255);
			ret[2] = (byte)(b * 255);
			return ret;
		}

		byte[] toRGB()
		{
			int h = hi();
			switch(h)
			{
			case 0:
				return makeRGB(v,t(),p());
			case 1:
				return makeRGB(q(),v,p());
			case 2:
				return makeRGB(p(),v,t());
			case 3:
				return makeRGB(p(),q(),v);
			case 4:
				return makeRGB(t(),p(),v);
			default:
				return makeRGB(v,p(),q());
			}
		}
	}

	static final int width = 640;
	static final int height = 480;
	static final int maxColor = 360;
	static final int maxIterations = 40;
	static final double zoomFact = 0.8;
	static final double center = -0.65;

	static final double xInc = width / (200000 * zoomFact);
	static final double yInc = height / (150000 * zoomFact);

	static final double sat = 0.85;
	static final double val = 0.85;

	static byte[][] makeColorMap(int nbCols)
	{
		byte[][] out = new byte[nbCols][];
		for(int i = 0; i < nbCols; i++)
			out[i] = new HSV((360.0 * i) / (nbCols + 1),sat,val).toRGB();
		return out;
	}

	static byte[][] colorMap = makeColorMap(Math.min(maxIterations,maxColor));

	static Complex c(int i, int j)
	{
		return new Complex(xInc * i + center - xInc * width / 2,
			yInc * j - yInc * height / 2);
	}

	static int pixel(Complex c)
	{
		Complex z = new Complex(0.0,0.0);
		for(int i = maxIterations; i >= 0; i--)
		{
			z = z.mul(z).add(c);
			if(z.absq() >= 4.0)
				return i;
		}

		return -1;
	}

	static byte[] black = new byte[] { 0,0,0 };

	static byte[] color(int iterations)
	{
		if(iterations == -1)
			return black;
		else
			return colorMap[iterations % colorMap.length];
	}

	static void render(OutputStream out) throws IOException
	{
		for(int j = 0; j < height; j++)
			for(int i = 0; i < width; i++)
				out.write(color(pixel(c(i,j))));
	}

	static void writePPMHeader(OutputStream out) throws IOException
	{
		out.write("P6\n".getBytes("ASCII"));
		out.write(Integer.toString(width).getBytes("ASCII"));
		out.write(" ".getBytes("ASCII"));
		out.write(Integer.toString(height).getBytes("ASCII"));
		out.write("\n255\n".getBytes("ASCII"));
	}

	static void run() throws IOException
	{
		BufferedOutputStream out = new BufferedOutputStream(
			new FileOutputStream("out.ppm"));
		try
		{
			writePPMHeader(out);
			render(out);
		}
		finally
		{
			out.close();
		}
	}

	public static void main(String[] args) throws IOException
	{
		for(int i = 0; i < 20; i++)
		{
			long start = System.currentTimeMillis();
			run();
			System.out.println(System.currentTimeMillis() - start);
		}
	}
}

Annotation: Faster pixel(); avoids memory allocation

Author: slava
Mode: java
Date: Thu, 24 Sep 2009 08:11:20
Plain Text |
	/* With this change, Java runs the benchmark as fast as Factor. */
	static int pixel(Complex c)
	{
		double zr = 0.0, zi = 0.0;
		for(int i = maxIterations; i >= 0; i--)
		{
			double zzr = zr * zr - zi * zi;
			double zzi = zr * zi * 2;
			zr = zzr + c.real;
			zi = zzi + c.imag;
			if(zr * zr + zi * zi >= 4.0)
				return i;
		}

		return -1;
	}

New Annotation

Summary:
Author:
Mode:
Body: