package image;

import math.number.NumberComplex;
import stdlib.Color;
import stdlib.Picture;

/*************************************************************************
 *  Compilation:  javac NewtonChaos.java
 *  Execution:    java NewtonChaos N
 *  Dependencies: Picture.java Complex.java
 *  
 *  Plot an N-by-N grid of points showing which of the four roots 
 *  that Newton's method converges to in the 2-by-2 box centered at (0, 0).
 *
 *************************************************************************/

public class NewtonChaos {

    // return number of Mandelbrot iterations to check z = x + iy
    static Color newton(NumberComplex z) {
        double EPSILON = 0.00000001;
        NumberComplex four = new NumberComplex(4, 0);
        NumberComplex one  = new NumberComplex(1, 0);

        NumberComplex root1 = new NumberComplex( 1,  0);
        NumberComplex root2 = new NumberComplex(-1,  0);
        NumberComplex root3 = new NumberComplex( 0,  1);
        NumberComplex root4 = new NumberComplex( 0, -1);

        for (int i = 0; i < 100; i++) {
        	NumberComplex f  = z.times(z).times(z).times(z).minus(one);
        	NumberComplex fp = four.times(z).times(z).times(z);
            z = z.minus(f.over(fp));
            if (z.minus(root1).mod() <= EPSILON) return Color.WHITE;
            if (z.minus(root2).mod() <= EPSILON) return Color.RED;
            if (z.minus(root3).mod() <= EPSILON) return Color.GREEN;
            if (z.minus(root4).mod() <= EPSILON) return Color.BLUE;
        }  
        return Color.BLACK;
    }


    public static void main(String[] args) {
//        int N = Integer.parseInt(args[0]);
        int N = 512;
        double xmin   = -1.0;
        double ymin   = -1.0;
        double width  =  2.0;
        double height =  2.0;

        Picture pic = new Picture(N, N);

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                double x = xmin + i * width  / N;
                double y = ymin + j * height / N;
                NumberComplex z = new NumberComplex(x, y);
                Color color = newton(z);
                pic.set(i, j, color);
            }
        }
        pic.show();
    }

}
