It turned out that converting my old algorythm into 3D is not as easy as I expected

this is how far Iâ€™ve got so far:

```
/**
* Contour lines example in 3D
* I call it
* Holy Mountain Peaks
* (you'll see why ;)
* (still messy, still needs corrections and improvements)
* drag mouse to rotate the scene
*/
final static int W = 512; // width of the hight map
final static int H = 512; // height of the hight map
final static float k = 0.03; //noise coefficient. play with it to get more or less Â«roughÂ» land
final static int l = 10; //show hight differense with this many contour lines
final static color c0 = #000000; //color to draw background
final static color c1 = #ffcc88; //color to draw contour lines
final static color c2 = #8844ff; //contour to stroke mesh
final color c3 = color(128,0,255,128); //contour to fill mesh
float hs = 8.0; // horisontal scale
float vs = 64.0; // vertical scale;
float[][] m; // the hight map
int[][] ip; // isopoints
float ax, ay; //angles to turn the map in 3D
PShape mesh;
void setup() {
size(1024, 512, P3D);
/* initialize map with perlin noise */
m = new float[W][H];
for (int j=0; j<H; j++) {
for (int i=0; i<W; i++) {
m[i][j] = noise((W+i)*k,(H+j)*k);
}
}
/* inspect our map to mark cells where the contour line vertices would be */
ip = new int[W][H];
for (int j=0; j<H; j++) {
for (int i=0; i<W; i++) {
if (i>0 && j>0 && i<W-1 && j<H-1) {
int h0 = round(m[i][j]*l); //get and adjust height at this point
int hw = round(m[i-1][j]*l); //get western neighbour's height
int hn = round(m[i][j-1]*l); //get nothern neighbour's height
int he = round(m[i+1][j]*l); //get eastern neighbour's height
int hs = round(m[i][j+1]*l); //get southern neighbour's height
if (h0>hw || h0>hn || h0>he || h0>hs) { //if this point is higher
ip[i][j] = h0;
} else {
ip[i][j] = -1;
}
} else {
ip[i][j] = -1;
}
}
}
ax = 0;
ay = 0;
/* build our mesh */
mesh = createShape();
mesh.beginShape(TRIANGLES);
mesh.strokeWeight(1);
mesh.stroke(c2);
mesh.fill(c3);
for (int j=0; j<H-1; j++) {
for (int i=0; i<W-1; i++) {
mesh.vertex(hs*(W/2-i), -l*m[i][j]*vs, hs*(H/2-j));
mesh.vertex(hs*(W/2-(i+1)), -l*m[i+1][j]*vs, hs*(H/2-j));
mesh.vertex(hs*(W/2-(i+1)), -l*m[i+1][j+1]*vs, hs*(H/2-(j+1)));
mesh.vertex(hs*(W/2-i), -l*m[i][j]*vs, hs*(H/2-j));
mesh.vertex(hs*(W/2-(i+1)), -l*m[i+1][j+1]*vs, hs*(H/2-(j+1)));
mesh.vertex(hs*(W/2-i), -l*m[i][j+1]*vs, hs*(H/2-(j+1)));
}
}
mesh.endShape();
}
void draw() {
background(c0);
pushMatrix();
translate(width/2, height+l*vs, -4*height);
rotateX(ax);
rotateY(ay);
/* draw the mesh */
shape(mesh);
/* draw them contour lines */
noFill();
strokeWeight(2);
stroke(c1);
for (int j=0; j<H; j++) {
for (int i=0; i<W; i++) {
if (i>0 && i<W-1 && j>0 && j<H-1) {
if (ip[i][j]>=0) {
int h0 = ip[i][j];
/* we'll inspect neighbourhood to east and south
* and draw lines to those points if they are marked with the same height */
if (ip[i+1][j]==h0) { //*east
line(hs*(W/2-i), -h0*vs, hs*(H/2-j), hs*(W/2-i-1), -h0*vs, hs*(H/2-j));
}
if (ip[i-1][j+1]==h0) { //*south-west
line(hs*(W/2-i), -h0*vs, hs*(H/2-j), hs*(W/2-i+1), -h0*vs, hs*(H/2-j-1));
}
if (ip[i][j+1]==h0) { //*south
line(hs*(W/2-i), -h0*vs, hs*(H/2-j), hs*(W/2-i), -h0*vs, hs*(H/2-j-1));
}
if (ip[i+1][j+1]==h0) { //*south-east
line(hs*(W/2-i), -h0*vs, hs*(H/2-j), hs*(W/2-i-1), -h0*vs, hs*(H/2-j-1));
}
}
}
}
}
popMatrix();
surface.setTitle("Drawing contour lines @ "+round(frameRate));
}
void mouseDragged() {
ax += (mouseY-pmouseY)/60.0;
if (ax<0) {
ax += TWO_PI;
}
if (ax>=TWO_PI) {
ax -= TWO_PI;
}
ay += (mouseX-pmouseX)/60.0;
if (ay<0) {
ay += TWO_PI;
}
if (ay>=TWO_PI) {
ay -= TWO_PI;
}
}
```