This takes some math functions and uses JavaScript and canvas to draw a 3D map. It was created for an
assignment on algorithms to traverse maps to find the highest point; a way to generate a varied set of
maps with a set of points was needed, but Google didn't turn anything up.
Also JavaScript's functional nature suits the problem very nicely.
Canvas is required, so Internet Explorer won't work with this page (until IE9 at least). Also generating, manipulating and drawing 200*200 points comes with a delay even on the best computers.
In a nutshell: Enter JavaScript code which returns an (x,y)->z function, hit Run, it'll be drawn.
Input - Output - Predefined functions - About
Click any of these pre-defined example maps to load them above.
// Simple hill var fd=shrink(translate(-30,50,toCartesian(function(r,t){return r;}))); return function(x,y){ return 2*(1-fd(x,y)); };
// Large hills var fa=shrink(rotate(Math.PI/5, zoom(5,function(x,y){return Math.sin(x)*Math.cos(y);}))); var fd=shrink(translate(-30,-40,toCartesian(function(r,t){return r ;}))); return function(x,y){ return 2*(1-fd(x,y))+fa(x,y); };
// Small hills var fa=shrink(rotate(Math.PI/7, zoom(1.5, function(x,y){return Math.sin(x)*Math.cos(y);}))); var fd=shrink(translate(-50,30,toCartesian(function(r,t){return r;}))); return function(x,y){ return 2*(1-fd(x,y))+fa(x,y); };
// Large ripples var fa=shrink(translate(40,40,toCartesian(function(r,t){return r;}))); var fd=shrink(zoom(1.5, toCartesian(function(r,t){return Math.sin(r);}))); return function(x,y){ return fd(x,y)+2*(1-fa(x,y)); };
// Small ripples var fa=shrink(translate(-25,15,toCartesian(function(r,t){return r;}))); var fd=shrink(zoom(0.5, toCartesian(function(r,t){ return Math.sin(r); }))); return function(x,y){ return fd(x,y)+2*(1-fa(x,y)); };
// Large ripples with radial spokes var fa=shrink(translate(40,40,toCartesian(function(r,t){return r;}))); var fd=shrink(zoom(1.5, toCartesian(function(r,t){return Math.sin(r);}))); var fc=shrink(toCartesian(function(r,t){return Math.sin(t*20);})); return function(x,y){ return fd(x,y)+2*(1-fa(x,y))+fc(x,y)/2; };
// Small ripples with radial spokes var fa=shrink(translate(-25,15,toCartesian(function(r,t){return r;}))); var fd=shrink(zoom(0.5, toCartesian(function(r,t){return Math.sin(r);}))); var fc=shrink(toCartesian(function(r,t){return Math.sin(t*20);})); return function(x,y){ return fd(x,y)+2*(1-fa(x,y))+fc(x,y)/2; };
// Small layered circular plateaus var cycleLength=6; var a=shrink(toCartesian(function(r,t){ var lastPlateau = r - (r % cycleLength); if( lastPlateau <= r && r < lastPlateau+(cycleLength/2) ) return lastPlateau; else return lastPlateau+cycleLength*(-Math.cos(Math.PI*(r%(cycleLength/2))/(cycleLength/2))+1)/2; } )); return function(x,y) { return (1-a(x,y)); };
// Large layered circular plateaus var cycleLength=14; var a=shrink(toCartesian(function(r,t){ var lastPlateau = r - (r % cycleLength); if( lastPlateau <= r && r < lastPlateau+(cycleLength/2) ) return lastPlateau; else return lastPlateau+cycleLength*(-Math.cos(Math.PI*(r%(cycleLength/2))/(cycleLength/2))+1)/2; } )); return function(x,y) { return (1-a(x,y)); };
// Default return function(x,y){ return x+y; };
Enter some JavaScript which returns a function(x,y)->z , domain x=-100 to 100, y=-100 to 100
The following helper functions are available: