Created with
NetLogo version NetLogo 4.0.4

Running with NetLogoLite.jar version 404.

This model produces simulated terrain using a variety of algorithms

Set the required parameters, click the buttons.

Midpoint Displacement:

Notice how fast it is. This is because the implementation avoids use of ASK PATCHES and MOD, and instead directly creates agentsets of patches from the previous iterations patches.

at-points

patch-set

watershed-model ;; also has a terrain generator, though it's rather primitive, special purpose, and silly.

http://www.lighthouse3d.com/opengl/terrain/index.php3?mpd

http://www.lighthouse3d.com/opengl/terrain/index.php?mpd2

http://en.wikipedia.org/wiki/Diamond-square_algorithm

http://www.gameprogrammer.com/fractal.html#diamond

NetLogo Version: NetLogo 4.0.4

globals [ ] patches-own [ v ;; elevation _v ;; floor of elevation * scalar ] to startup setup end to setup ca display-message [ "Welcome to the Terrain Generator Workshop" "" "Featuring an assortment of simulated terrain generators" "" "Press the generator button to generate a sample" ] end to go setup-terrain-midpoint-displacement-fractal smoothness end to setup-terrain cp ct end to setup-terrain-midpoint-displacement-fractal [ #roughness ] ;; note that, unlike other implementations found on the web ;; this implementation does NOT require the field to be square, nor ;; does it require the field grid to be sized at (1 + 2^n) ;; i.e. it world for any size gird of any ratio. ;; this is because it dynamically finds the minimum power of two needed ;; to correctly populate the provided grid. let time0 timer setup-terrain let r #roughness let md 1 let rr 2 ^ (- r) ;; which dimention is smaller? let dim min (list world-width world-height) ;; use that dimension to figure out the initial gap to use let g 2 ^ ( floor (log (dim ) 2) - 1 ) let diamond-set 0 let square-set 0 ask patches [ set v 0 ] set diamond-set (patch-set patch 0 0) repeat floor log world-width 2 [ set square-set (patch-set [my-parent-corners g] of diamond-set) ask square-set [ set v v + plus-or-minus md + mean [ v ] of my-parent-corners g ] set diamond-set (patch-set [ my-parent-points g ] of square-set) ask diamond-set [ set v v + plus-or-minus md + mean [ v ] of my-parent-points g ] set g g / 2 set md md * rr ] let time1 timer let timespan floor (time1 - time0) if timespan < 1 [ set timespan "< 1" ] print (word "MDF terrain generated for " count patches " patches in " timespan " seconds.") compress color-default end to setup-terrain-bespoke-atoll [ ] setup-terrain let deepest 0 let peaks 0 ; build an irregular, circular island ; with a shallow center lagoon cp ; create overall ring shape ask patches [ let temp distancexy 0 0 ; sin wave, 0 at center, peak in middle, 0 at corners let temp3 temp * 360 / 3 / 100 ; scale as distance from edge let temp2 2 * sin ( temp * 180 / max-pxcor ) * ( max-pxcor - abs pxcor) / max-pxcor * ( max-pycor - abs pycor) / max-pycor set v world-width * sin temp3 * temp2 ] ; add random peaks and dips, repeat repeat max-pxcor [ ; "picking peak/pit location" ask patch 0 0 [ set v (- world-width) ] set peaks n-of max-pxcor patches ; "talking to peaks" ask peaks [ set v v + max-pxcor * random 2 * 2 - 1 ] ] ;; ; erode, just a bit repeat 4 [ ask patch 0 0 [ set v min-pxcor ] diffuse v .8 ] ; add "stress ridges" ask patches [ ; get distance from center let temp distancexy 0 0 let temp2 0 ; get angle from center ifelse temp = 0 [ set temp 1 set temp2 0 ] [ set temp2 ( towardsxy 0 0 + 180 ) if temp2 > 360 [ set temp2 temp2 - 360 ] ] ; set number of ridges let temp3 temp2 * 50 set v v + (max-pxcor * sin temp3 + sin temp * .2 )/ temp ] ;; apply non-linear scaling of v ask patches [ set v v * v ] compress color-default end to-report my-parent-corners [ g ] let -g (- g) report patches at-points (list (list -g g) (list g g) (list g -g) (list -g -g ) ) ;; to-do: maybe pre-calculate the at-points lists for each generation ;; save some time over generating them over and over end to-report my-parent-points [ g ] let -g (- g) report patches at-points (list (list 0 -g ) (list g 0) (list 0 g) (list -g 0) ) end to-report plus-or-minus [ n ] report n - 2 * random-float n end to setup-terrain-circles [ #number #connect ] setup-terrain let mr world-width * #connect let mrd mr / #number * .9 let r 0 let h 0 let a 0 let pm 1 let candidates [ patches in-radius (world-width * (.75 - #connect)) ] of patch 0 0 ask n-of #number candidates [ set r (.1 + random-float .5) * mr set h (.1 + random-float 1) * mr if subtract? [ set pm (((random 2)* 2)- 1) ] set a 180 / r ; ask patches in-radius r [ set v v + pm * h * cos ( .5 * a * distance myself ) ] set mr mr - mrd ] compress color-default end to setup-terrain-line-dropper [ #number #roundness ] setup-terrain ;; this has got to be super naive. ;; that is, there has to be a better way to decide on what side ;; of a line a point lies. ;; pick a center point and an angle ;; if the difference tween the angle and the heading from this point ;; to the center point is > 0 (and less than 180, natch) ;; then increment this patch ;; i.e. elevate patches on only one side of the line repeat #number [ let center one-of patches let angle random 360 let inc .5 * random-float 1 let curve .5 * world-width * .1 * .5 * (#roundness + random-float #roundness) ask center [ set v v - inc ] ask patches with [ self != center ] [ ;; depending on which side of the line this patch falls... ifelse subtract-headings angle towards center > 0 [ let dist-from-line (distance center * sin (180 - (angle - towards center ) ) ) let inc' inc ;; calculate a smooth transition from one plane to the other if dist-from-line <= curve [ set inc' inc' * cos (( (curve - dist-from-line) / curve ) * 180 ) ] set v v + inc' ] [ set v v - inc ] ] ] compress color-default end to setup-terrain-sin-wave-overlay [ #number #max-frequency ] setup-terrain repeat #number ;; apply this number of waves to the view [ let freq random-float #max-frequency let amp random-float 1 let offset random-float 1 * freq let angle random-float 360 let wx sin angle let wy (- cos angle) ask patches [ set v v + amp * (sin (offset + freq * (pxcor * wx + pycor * wy))) ] ;; uncomment the below lines to see the application of each layer ; color-sample ; display ; wait .1 ] compress color-default end to setup-terrain-particle-deposition [ #iterations ] setup-terrain let sp patch 0 0 repeat #islands [ let md 1 ; #max-displacement let od md ; let r #roughness let md-d 1 / #iterations let p sp let op p repeat #iterations [ ask p [ set p one-of neighbors4 ; set v v + random-float md ] while [ is-patch? p ] [ ask p [ set op p ; set v v + random-float md set p one-of neighbors4 with [ v < [ v ] of myself and atan 1 (v - [v] of myself) > 45 ] ] ] ask op [ set v v + random-float md ] set p op ; op set md md - md-d ] set sp one-of patches ] compress color-default end ;;_,-'-._,-'-._,-'-._,-'-._,-'-._,-'-._,-'-. ;; COMMONI PROCEDURES ;;_,-'-._,-'-._,-'-._,-'-._,-'-._,-'-._,-'-. to color-default ifelse default = 4 [ color-monochrome map-color ][ ifelse default = 3 [ color-false-color-contour map-color ][ ifelse default = 2 [ color-cartegraphic-contour ][ ifelse default = 1 [ color-contours divisions ][ color-contours-mono divisions map-color ]]]] end to compress let new-max 9.9 let minv min [ v] of patches let maxv max [ v ] of patches let spanv maxv - minv if-else spanv != 0 [ let s new-max / spanv ask patches [ set v (v - minv) * s ] ] [ ask patches [ set v 0 ] ] end to color-mono-simple [ #color ] ask patches [ set pcolor v - 5 + #color ] end to color-monochrome [ #color ] ;; assumes v has been scaled to 0.0...9.9 ;; color the patches using V as the brightness, using the given color ask patches [ let pc v - gray + #color if-else shaded? [ set pc scale-color #color (2.5 + .5 * v) 0 9.9 let s patch-at 1 -1 if is-patch? s [ if-else [ v] of s < v [ set pc max (list (pc - 2) (pc - (pc mod 10))) ] [ set pc min (list (pc + 2) (9.9 + pc - (pc mod 10))) ] ] ] [ ] set pcolor pc ] end to color-contours [ #div ] ask patches [ set _v floor( #div * v) ] ask patches [ let n count neighbors with [ _v = [ _v ] of myself ] if n < 1 [ set n 1 ] set pcolor scale-color _v n 0 8 ] end to color-contours-mono [ #div #color ] ask patches [ set _v floor ( #div * v ) ] ask patches [ let n 1.2 * count neighbors with [ _v = [ _v ] of myself ] if n < 1 [ set n 1 ] set pcolor scale-color #color n 0 8 ] end to color-false-color-contour [ #div ] ;; color the patches as a false-color contour map ;; color slider determines the number of colors in the map ifelse graduated? [ let $div 10 * (#div - 1 ) / 9.9 ask patches [ set pcolor 5 + int(v * $div) ] ] [ ask patches [ set pcolor 5 + 10 * int(v * #div) ] ] display end to color-no-scale [ #color ] ;; color the patches using V as the brightness, using the given color ;; does not assume v has been scaled let minv min [ v] of patches let maxv max [ v ] of patches let spanv maxv - minv let cs spanv * .1 let mins minv - cs let maxs maxv + cs ;; default: V = brightness ask patches [ set pcolor scale-color #color v minv maxv ] end to color-cartegraphic-contour ;; color the patches using typical terrain map colors ;; default: V = brightness ask patches [ ifelse v < 3 [ set pcolor scale-color blue v 0 4 ][ ifelse v < 4 [ set pcolor scale-color yellow (- v) -4.5 -2.5 ][ ifelse v < 6 [ set pcolor scale-color lime v 0 12 ][ ifelse v < 8 [ set pcolor scale-color green v 4 12 ][ ifelse v < 9 [ set pcolor scale-color brown v 6 12 ][ set pcolor scale-color gray v 5 9.9 ]]]]] ] end to setup-3d-vis if is-applet? [ user-message "Note, this feature does not work in applet mode.\n\nPlease run the model directly, to use the 3d Viewer." stop ] let alt world-width * .1 if count turtles != count patches [ ct foreach reverse sort patches [ ask ? [ sprout 1 [ set shape "line" __set-line-thickness 2 set heading 0 ] ] ] ] ask turtles [ set size v * alt set color pcolor ] end to clear-3d-vis ask turtles [ die ] user-message "If it is open, please close the 3d vis window." end ;;_,-'-._,-'-._,-'-._,-'-._,-'-._,-'-._,-'-. ;; UTILITY PROCEDURES ;;_,-'-._,-'-._,-'-._,-'-._,-'-._,-'-._,-'-. to display-message [ message-list ] let pr (max-pycor - 4 ) foreach message-list [ ask patch max-pxcor pr [ set plabel ? set plabel-color white ] set pr pr - 3 ] end

terrain-workshop_2009

View or download the complete model file (to download: right-click, save-link-as):

-- Download terrain-workshop_2009 --