Marko,
By going 3d you end up with a cube fully of neatly spaced points.
Means we would need a 3d triangulation to exploit it.
If we want to do terrain we have to go 2.5d, that is a good random set of
points, as provided by bridson with elevations.
Elevations can be provided by yet another Noise Function namely "Perlin Noise".
Here a small program not extensively tested to illustrate what I mean:
;; ;
;; PerlinNoise_2d by ymg ;
;; ;
;; Function to Generate Perlin Noise in Two Dimension ;
;; ;
;; From peudo-code by Hugo Elias at: ;
;; http://freespace.virgin.net/hugo.elias/models/m_perlin.htm ;
;; ;
;; Notes: Variables persistence and number_of_octaves are defined in calling ;
;; Program, although they could be added as arguments. ;
;; ;
(defun PerlinNoise_2D
(x y
/ p n frequency amplitude total
)
(/ (setq x
4294967296.0 s
(rem (1+ (* 1664525.0 s
)) x
)) x
) )
(+ (/ (+ (noise
(1- x
) (1- y
)) (noise
(1+ x
) (1- y
)) (noise
(1- x
) (1+ y
)) (noise
(1+ x
) (1+ y
))) 16) (/ (+ (noise
(1- x
) y
) (noise
(1+ x
) y
) (noise x
(1- y
)) (noise x
(1+ y
))) 8) (/ (noise x y) 4)
)
)
(defun interpolatenoise
(x y
/ intx fracx v1 v2 v3 v4 i1 i2
) fracx (- x intx) fracy (- y inty)
v1 (smoothmoise intx inty)
v2
(smoothmoise
(1+ intx
) inty
) v3
(smoothmoise intx
(1+ inty
)) v4
(smoothmoise
(1+ intx
) (1+ inty
))
i1 (interpolate v1 v2 fracx)
i2 (interpolate v3 v4 fracx)
)
(interpolate i1 i2 fracy)
)
;; ;
;; Cosine Interpolation ;
;; ;
(defun interpolate
(a b x
) )
;; ;
;; in_range by ElpanovEvgeniy (recursive) ;
;; ;
;; Similar to the Python Function ;
;; ;
(if (or (and (> i
0) (< s e
)) (and (< i
0) (> s e
))) (cons s
(in_range
(+ i s
) e i
)) )
)
;; ;
;; Body of Function PerlinNoise ;
;; ;
p persistence
)
total (+ total (* (interpolatenoise (* x frequency) (* y frequency)) amplitude))
)
)
total
)
;; ;
;; Poisson Disk Sampling per Bridson Algorithm ;
;; ;
;; See: http://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf;
;; http://devmag.org.za/2009/05/03/poisson-disk-sampling/ ;
;; ;
;; Will return a Random Set of points with a minimum distance between them ;
;; ;
(defun bridson
(ll ur mindist
/ a al cells cellsize grid i ind k p p1 p2 pl r tcl x y
) cellSize
(/ mindist
(sqrt 2)) x (ceil (/ width cellsize))
y (ceil (/ height cellsize))
p1
(list (rand width
)(rand height
)) al
(list 0) ; Initialize Active List with index of First Point;
)
(init2d grid x y) ; Initialize the grid to all -1, then ;
)
r (* mindist (+ 1.0 (rand 1.0)))
)
(setq cells
(ptsaround grid ind
))
(setq tcl
(tooclosep p2 cells pl
)) )
)
)
)
)
)
)
)
)
(defun init2d
(grid x y
/ i j
) )
)
)
(defun ptsaround
(grid ind
/ i j rtn tmp
)
(if (and (< -1 i x
) (< -1 j y
)) )
)
)
)
rtn
)
(defun tooclosep
(p cells pl
/ pc rtn
) )
)
)
rtn
)
;; Random number generator, Seed must remain global. LeeMac ;
;; Will return a real in the range 0...rng ;
(* (/ (setq x
4294967296.0 seed
(rem (1+ (* 1664525.0 (cond (seed
) ((getvar 'DATE
))))) x
)) x
) rng
) )
;; Floor function, Returns the largest integer not greater than x. ;
;; Ceiling function, Returns the smallest integer not less than x. ;
(defun c:gen_terrain
(/ ** p1 p2 bb md
)
number_of_octaves 6
vexag 10
)
md
(getdist "\nMinimum Distance Between Points: ") )
;; Applying Perlin Noise to our Point List to Get Z Values ;
;; Drawing our Point List to the Screen ;
(entdel **) ; If you want to delete the rectangle after selection. ; )
We could use the same "Perlin Noise" function to generate a random contour instead of
a rectangle.
But essentially this is the technique they use in Game Software to generate terrain.
There is of course more details to attend, like coloring or texturing as a function of
heigth etc.
Heres a crude one generated with persistance set at 0.25 and no_of_octave 6.
I did not loft it down to zero. There could be bugs lurking in there as I did not
test it extensively.
More details on Hugo Elias'es page :
http://freespace.virgin.net/hugo.elias/models/m_perlin.htmymg