**Based on: **Topographic Form by Sture Johannesson, 1976

**Category: **direct

**Description: **

This sketch does not run in the browser.

/* Part of the ReCode Project (http://recodeproject.com) Based on "Topographic Form" by Sture Johannesson Originally published in "Computer Graphics and Art" v1n2, 1976 Copyright (c) 2014 Jay Kominek - OSI/MIT license (http://recodeproject/license). */ /* @pjs pauseOnBlur="true"; */ /* Part of the ReCode Project (http://recodeproject.com) Based on "Topographic Form" by Sture Johannesson Originally published in "Computer Graphics and Art" vol1 no2, 1976 Copyright (c) 2014 Jay Kominek - OSI/MIT license (http://recodeproject.com/license). */ // by Sture Johannesson and Sten Kallin, Malmo, Sweden class RaisedArc { float cx, cy; float r; float width; float start, stop; float height; RaisedArc(float x_, float y_, float r_, float width_, float start_, float stop_, float height_) { cx = x_; cy = y_; r = r_; width = width_/2.0; height = height_; start = start_; stop = stop_; } // the arc is effectively -pi/2 to pi/2 of cosine, // stretched to the specified width and height, and extruded // along the arc centered at x,y and r units from there, // run from start radians to stop radians. float computeHeight(float px, float py) { float rx = px - cx, ry = py - cy; float theta = atan2(ry, rx) + PI; float distance = sqrt(rx*rx + ry*ry); if( (start <= theta) && (theta <= stop) ) { float wp = abs(r - distance) / width; // you can comment this out to get "ringing" // from the arcs. if(wp >= 1.0) wp = 1.0; return height * cos(PI/2.0 * wp); } else return 0.0; } } RaisedArc[] arcs; int sh = 600; int sw = 3*(sh/2); // you can make a cleaner looking version by permitting smoothing, // and making the fx step much, much smaller. // decreasing the fx step eliminates the slight appearance of perspective at // the ends of the partial arcs, though. (you can see evidence of large fx // steps in the original about halfway up the outside of the left arc.) void setup() { arcs = new RaisedArc[4]; arcs[0] = new RaisedArc( 0, 0, 15, 9, 0, 2*PI, 10); arcs[1] = new RaisedArc(-30, 0, 15, 9, PI, 2*PI, 10); arcs[2] = new RaisedArc(-30, 0, 15, 9, 0, PI/2, 10); arcs[3] = new RaisedArc( 30, 0, 15, 9, 0, 1.5*PI, 10); size(sw, sh, P3D); noSmooth(); noFill(); strokeWeight(0.8); } void draw() { // black on white background(255); stroke(0); // the XY plane is tilted, but it is hard to tell float rotation = 28.12 / 180.0 * PI; // because the projection is orthographic ortho(); // scoot us to the middle translate(sw/2, sh/2, 0); // scale things up. values made up to fit the window. scale((sw/2)/60*1.05, (sh/2)/41*1.05, 1.0); rotate(rotation, 1, 0, 0); beginShape(); for(int iy = -41; iy < 41; iy++) { float fy = (float)iy; // this flip flops the direction in which we're drawing. no way to know // for sure from the original, but it would work better with any sort of // scanning display device (storage scopes, etc), and simplifies the little // connections at the end. float fx_start = ((iy%2)!=0)?-60.0:60.0; float fx_stop = -fx_start; float fx_step = ((iy%2)!=0)?1.0:-1.0; for(float fx = fx_start; ((iy%2)!=0)?(fx<=fx_stop):(fx>=fx_stop); fx += fx_step) { float fz = 0.0; // height of our surface is the height of the tallest arc at that spot. for(int j=0; j<4; j++) { float h = arcs[j].computeHeight(fx, fy-0.5); if(h > fz) fz = h; } // emit a vertex. i bet this part was more complicated in the original. vertex(fx,fy,fz); } } endShape(); }