PERLIN_SIZE is 4095 but in getPerlin +1 is added. getPerlin creates your random number array. These are just normal random numbers but not gradients as in true perlin noise.

The critical line is of = x + 16 * y + 256 * z. PERLIN_YWRAPB and PERLIN_ZWRAPB are just the multipliers expressed with bit operators. x,y,z are the input parameters you entered in your noise function.

The variable of is used to pick the random number out of the array of 4096.

The equation makes sense, because for the 3D case you get 16x16x16 original values. However, that also means that for 2D, that of is the same for the pairs x=17, y=2 (of=49) and x=33 and y=1 (of=49).

For 2D you could use a multiplier of 64 (by changing PERLIN_YWRAPB). This would allow a 64x64 grid in the 4096 array.

You can easily check that by using noise(16 * i,j), which gives you diagonal lines.

noise(i,256 * j) and noise(16 * 256 * i,j) give you vertical or horizontal lines because you go beyond the 4096 threshold (see my code below).

Values between the integers are interpolated with cosine. So 1/8192 = 0.0001 would be interpolated between 0 and 1.

```
int gridsize=64;
float elevation;
float[][] mark = new float[gridsize][gridsize];
void setup(){
size(700,700);
background(125);
dots();
}
void draw(){
for (int i=0; i < gridsize;i++){
for (int j=0; j < gridsize; j++){
stroke(255, mark[i][j], mark[i][j]);
strokeWeight(10);
point(i*10+10,j*10+10);
}
}
}
void dots(){
for (int i=0; i < gridsize;i++){
for (int j=0; j < gridsize; j++){
noiseSeed(10);
elevation = map(noise(i,256*j,0),0,1,0,255);
mark[i][j] = elevation;
}
}
}
```