public class Noise
{
    int height = 200;
    int width = 200;
    double noise[][]; 

    public Noise(int w,int h)
    {
        height=h;
        width = w;
        if (width<height) width = height;
        noise = new double[width][height];
        for (int i=0; i < width; i++)
           for (int j=0; j < height; j++)
              noise[i][j] = Math.random();
    }

    // linearly interpolate between points in noise array
    public double linear(double u, double v)
    {

        int iu = (int) u;
        int iv = (int) v;
        double du = u - iu;
        double dv = v - iv;

        iu = iu % width;
        iv = iv % height;
        int ip = (iu+1) % width;
        int iq = (iv + 1) % height;
     
        double bot = noise[iu][iv] + du*(noise[ip][iv]-noise[iu][iv]);
        double top = noise[iu][iq] + du*(noise[ip][iq]-noise[iu][iq]);
        return bot+dv*(top-bot);
    }
    
   

    // linearly interpolate between noise at different resolutions
    public double turbulence(int u, int v)
    {
        double t = 0;
        int count = 0;
        double scale = 8;
        double pixel_size = 1;
        while ( scale > pixel_size) {
            count++;
            t += linear((u/scale), (v/scale)) ;
            scale /= 2;
        }
        return t/count;
    }

}