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: