Topographical map

Hi @LordCacops,

There’s a thread about that exact same topic on the old Processing forum.

The suggested solution is to:

  • draw noise on a graphics buffer (noise is mapped against a domain ranging from 0/black to 255/white)
  • use the blobDetection library to detect the white spots
  • run that blob detection multiple times on the same image (your PGraphics object), increasing the threshold each time.

You’ll end-up with multiple concentric blobs whose faces will act as contour lines.
Here below an annotated example sketch (Python mode) based on your script that just does that:

add_library('blobDetection')
add_library('peasycam')

rows, cols = 100, 100    # number of rows and cols
scle = 7    # scale factor (how large is the output)
w, h = cols * scle, rows * scle    # width and height of the output map
factor = .05    # noise factor
levels = 40    # max number of contour lines
elevation = 200    # height domain of contour lines

                    
def setup():
    size(1400, 800, P3D)
    ortho(-width>>1, width>>1, -height>>1, height>>1)
    smooth(8)
    
    cam = PeasyCam(this, 1000)
    
    # Drawing noise on an off-screen graphics buffer
    pg = createGraphics(cols, rows, P2D)
    pg.beginDraw()
    pg.loadPixels()
    for i in xrange(rows * cols): 
        n = noise(i%cols * factor, i/cols * factor) * 255 # scaling up the noise value to match the color range
        pg.pixels[i] = color(n)
    pg.updatePixels()
    pg.endDraw()


    # BLOB DETECTION
    # -> looking for white spots on the graphics buffer and circling them
    # -> repeating this task as many times as required, increasing the threshold each time to get concentric circles
    blobs = []
    for l in range(levels):
        b = BlobDetection(pg.width, pg.height)
        b.setThreshold(l/float(levels))
        b.computeBlobs(pg.pixels)
        blobs.append(b)
        
    # RENDERING
    # -> accessing each edge of each blob and drawing a line between its 2 vertices
    # -> storing the whole as a PShape object
    global contours 
    contours = createShape()
    contours.beginShape(LINES)
    for i in xrange(levels):
        contours.stroke(i*8, 255 - i*10, 235 + i)
        for n in range(blobs[i].getBlobNb()):
            b = blobs[i].getBlob(n)
            if b is not None:              
                for edge in range(b.getEdgeNb()):
                    v1 = b.getEdgeVertexA(edge)
                    v2 = b.getEdgeVertexB(edge)
                    if v1 is not None and v2 is not None:
                        contours.vertex(v1.x*pg.width*scle, v1.y*pg.height*scle, i * (float(elevation)/levels))
                        contours.vertex(v2.x*pg.width*scle, v2.y*pg.height*scle, i * (float(elevation)/levels))         
    contours.endShape(CLOSE)
    

def draw():
    background('#000000')
    translate(-w>>1, -h>>1)
    
    shape(contours)


(Note that it is 3D orthographic projected contour map looked at from above)

Also see the dedicated Flickr gallery by Cedric Kiefer to get an idea of the various outputs you could come-up with using that technic.

3 Likes