/*
 * Mandelbrot.java by Richard J. Davies
 * from `Introductory Java for Scientists and Engineers'
 * chapter: `JSGL, a Scientific Graphics Library for Java'
 * section: `Example - The Mandlebrot Set'
 *
 * This program draw the famous Mandelbrot set.
 */
import uk.co.jscieng.*;
import VisualNumerics.math.*;
import java.awt.Color;


public class Mandelbrot
{
  // The size of the window in pixels
  public static final int SIZE = 300;

  // The area of the set to show in the window
  public static final double LEFT = -2.1;
  public static final double RIGHT = 2.1;
  public static final double BOTTOM = -2.1;
  public static final double TOP = 2.1;

  // The maximum number of iterations to perform
  public static final int MAXITER = 100;

  // The colors to cycle to show iteration depth
  public static final Color[] colors = 
    { Color.red, Color.pink, Color.yellow,
      Color.cyan, Color.green, Color.magenta };


  // This method returns a color for an iteration depth.
  public static Color indexColor(int i)
  {
    // Return black if we hit our iteration limit.
    // Cycle through the colors array otherwise
    if (i == MAXITER)
      return Color.black;
    else
      return colors[i % colors.length];
  }


  // This method performs the iteration until
  // the complex number leave a circle of radius
  // 2 about the origin or MAXITER is reached.
  // It returns the number of iterations performed.
  public static int iterate(Complex c)
  {
    Complex z = c;
    int count = 0;

    while ((Complex.abs(z) < 2) && (count < MAXITER))
    {
      z = Complex.add(Complex.multiply(z, z), c);
      count++;
    }

    return count;
  }


  // The `main' method controls the drawing.
  public static void main(String[] argv)
  {
    double real, imag;
    int count;

    // Set up a graph window of the right size.
    SciGraph.showGraph(LEFT, RIGHT, BOTTOM, TOP,
                       SIZE, SIZE);

    // Iterate through all of its pixels
    for (int i=0; i<SIZE; i++)
      for (int j=0; j<SIZE; j++)
      {
        // Working out their position in the
        // complex plane
        real = LEFT + i * (RIGHT - LEFT) / SIZE;
        imag = BOTTOM + j * (TOP - BOTTOM) / SIZE;

        // Counting the number of iterations
        // needed at that point
        count = iterate(new Complex(real, imag));

        // And plotting that point in the
        // appropriate color.
        SciGraph.point(real, imag, indexColor(count));
      }
  }
}

