package math.diffeq;


import stdlib.Color;
import stdlib.Picture;
/**
 * 
 * @author Daniel
 *
 */
public class Laplace {

    public static void main(String[] args) {
    	int N = 512;
    	if(args.length > 0) {
    	    try {
    	        N = Integer.parseInt(args[0]);
    	    } catch (NumberFormatException e) {
    	        System.err.println("Argument" + " must be an integer");
    	        System.exit(1);
    	    }
    	}
    	int i, j, r;
        Picture pic = new Picture(N+1, N+1);
        double[][] V = new double[N+1][N+1];

        // precompute colors
        Color[] colors = new Color[101];
        for(i=0; i<=100; i++){
            int red   = (255 * i) / 100;
            int green = 0;
            int blue  = 255 - red;
            colors[i] = new Color(red, green, blue);
        }
        for(i=0; i<=100; i=i+10)
            colors[i] = Color.BLACK;
       
        // initialize all points with reasonable starting values for the potential
        for(i=1; i<N; i++)
            for(j=1; j<N; j++)
                V[i][j] = 51.0;
                
        // boundary conditions
        for(j=0; j<=N; j++) V[0][j] =  30; // left
        for(j=0; j<=N; j++) V[N][j] =  70; // right
        for(i=0; i<=N; i++) V[i][0] =   0; // bottom
        for(i=0; i<=N; i++) V[i][N] = 100; // top
                
        // numerically solve Laplace's equation	
        while(true) {

            // draw
            for(i=1; i<N; i++){
                for(j=1; j<N; j++){
                    int c = (int) Math.round(V[i][j]);
                    pic.set(i, N-1-j, colors[c]);
                }
            }
            pic.show();

            // repeat 100 times before drawing to screen
            for(r=0; r<25; r++)
                for(i=1; i<N; i++)
                    for(j=1; j<N; j++)
                        V[i][j] = 0.25* (V[i-1][j] + V[i+1][j] + V[i][j-1] + V[i][j+1]);

        }
    }
}