I decided to opt for the 2D version of this concept, as this is intended to host agents, as in an agent based simulation, and 3D might be too heavy memory wise.
I employed @LuckSmith 's method to use hight variables determining the shape of a three dimensional mesh in a different sketch, and with noiseSeed() managed to map that exact terrain into the hight value method that draws isolines by rounding up what would otherwise be grayscale values.
My tridimensional mesh had 180 columns by 90 rows, so to extrapolate precisely, I made the window for the isolines 180 by 90. This is TINY. I would want it to be at least 5 times as big, yet showing the same scaled map and same isolines, and preferably keeping the isolines one pixel thick.
/**
* Countour line example
* for https://discourse.processing.org/t/topographical-map/13302/4
* Press any key to toggle between viewing countour lines or hights (the lighter the higher)
*/
final static int W = 180; // width of the hight map
final static int H = 90; // height of the hight map
final static float k = 0.02; //noise coefficient. play with it to get more or less «rough» land
final static int l = 4; //show hight differense with this many contour lines
final static color c0 = #000000; //color to draw background
final static color c1 = #DB00CD; //color to draw isolines
float[][] z; // the hight map
boolean showHeightOrCountour = false;
//variables from the other program
//int cols, rows;
//int scl = 10; //scale
//int w = 1800; //width, adjustable//compare to uppercase versions of this
//int h = 900; //height, adjustable
float macroXoff = 0; //large noise offsets, horizontal (x) and vertical (y)
float macroYoff = 0;
//used for the sine
float ax = 0; //angle for the horizontal sine
float ay = radians(300); //angle for the horizontal sine
float inc = TWO_PI/55; //the smaller sine offset
float macroAx = 0;
float macroAy =0;
float macroInc = TWO_PI/55; //the larger sine offset
void setup() {
noiseSeed(15);
size(180, 90);
z = new float[W][H];
float yoff = 0;
for (int j=0; j<H; j++) {
float xoff = 0;
macroXoff = 0;
float ax = radians(300);
float macroAx = radians(350);
for (int i=0; i<W; i++) {
//m[i][j] = noise((W+i)*k,(H+j)*k);
float microNoise = map(noise(xoff, yoff), 0, 1, -30, 30);
float macroNoise = map(noise(macroXoff, macroYoff), 0, 1, -150, 150);
float sine = sin(ay)*80 + sin(ax)*80;
float macroSine = sin(macroAy)*60 + sin(macroAx)*60;
z[i][j] = sine + macroSine + microNoise + macroNoise;
//println(z[i][j]);
xoff += 0.2;//change offsets to control smoothness.
macroXoff += 0.05;
ax = ax + inc/2;
macroAx = macroAx + inc/5;
}
yoff +=0.2;
macroYoff += 0.05;
ay = ay + inc/2;
macroAy = macroAy + inc/2;
}
}
void draw() {
loadPixels();
for (int j=0; j<H; j++) {
for (int i=0; i<W; i++) {
if (!showHeightOrCountour) { //show height
//with map I normalize to gray
pixels[W*j+i] = color(map(z[i][j]*l,-200,200,0,1)*(255/l)); //show hight with l resolution
} else { //show contour
if (i>0 && i<W-1 && j>0 && j<H-1) {
int h0 = round(map(z[i][j]*l,-200,200,0,1)); //get and adjust height at this point
int hw = round(map(z[i-1][j]*l,-200,200,0,1)); //get west neighbour's height
int hn = round(map(z[i][j-1]*l,-200,200,0,1)); //get nothern neighbour's height
if (h0!=hw || h0!=hn) { //if any neighbour's height on a different «step» of hight…
pixels[W*j+i] = c1; //…draw contour
} else {
pixels[W*j+i] = c0; //…otherwise draw background
}
} else {
pixels[W*j+i] = c0;
}
}
}
}
updatePixels();
surface.setTitle("Drawing contour lines @ "+round(frameRate));
}
void keyPressed() {
showHeightOrCountour = !showHeightOrCountour;
}
I am also trying to figure out how to give each hight pleateau a different color.
Thanks in advance for any help.