NetLogo version NetLogo 3.0beta2
Running with NetLogoLite.jar version 302.
NetLogo Version: NetLogo 3.0beta2
; Watershed Model and Terrain Generator ; Version 1.1.2 ; James Steiner globals [ ; levels-changed ; obsolete, used to flag if levels changed, to notify 3d update peak ; the highest level of all the patches middle ; the mean of the elev and level valley ; the lowest elev of all the patches spread ; the difference between the valley and peak vm ; the valley-middle line, used for coloring pm ; the peak-middle line, used for coloring ; both of the above normally equal to spread and peak ticks ; count of flow-frames rendered, for by-eye estimation of fram rate ] breeds [ backdrops ; the backdrop of the 3d inset window nodes ; the points of the 3d rendering ] nodes-own [ my-patch ; the source patch linked to this node ox oy oe ; original coordinates px py pel ; projected coordinates pre-hide? ; part of the projection process ] patches-own [ elev ; "surface" level level ; "water" level, equals elev when dry ; may never be less than elev volume ; level - elev, the depth of the water, or the volume of water temp ; used for various things temp2 temp3 water-in water-out neighbors-nowrap ; the neighbors, without edge-wrapping ] to startup ; river-valley end to update-all ; apply color and, if required, labels no-display ; freeze display while updating color-all ; apply color label-all ; apply labels display ; refresh display ; set levels-changed 1 end to dry-all ; resets the "water" level to the elevation ; effectively drying the landscape ask patches [ set level elev ] calc-measures update-all end to diffuse-elev-nowrap ask patches [ set level .5 * ( elev + mean values-from neighbors-nowrap [ elev ] ) ] ask patches [ set elev level ] end to define-neighbors-nowrap ask patches [ set neighbors-nowrap neighbors in-radius-nowrap 2 ] end to river-valley locals [ lump-size num-lumps ] ; generates a passable simulation of the elevations of a river valley ; flowing north to south clear-turtles clear-patches define-neighbors-nowrap if presets? [ set river? true set drain? true set erupt? false set source-rate 2 set altitude? false set scale .5 set shift-x .45 set shift-y .45 ] note "creating valley contours" ; impress a valley shape ; store in LEVEL ask patches [ do-valley ] set valley min values-from patches [ level ] set peak max values-from patches [ level ] if valley = peak [ set valley valley - 2 set peak peak + 2 ] set spread peak - valley ;adjust valley to 0 .. 1 ask patches [ set elev ( level - valley ) / spread * screen-edge-x] note "adding random lumps" dry-all wait .5 set num-lumps sqrt (screen-size-x * screen-size-y) * ( 1 - lumpiness * .01 ) ask random-n-of num-lumps patches [ set lump-size 1 + screen-edge-x * .01 * (random-float lumpiness) without-interruption [ ask patches in-radius-nowrap lump-size [ set elev elev + lump-size - ( distance-nowrap myself ) ] ] ] note "tilting landscape" dry-all wait .5 ; tilt the landscape so everything runs downhill ; slope set by steepness ask patches [ set elev elev + (pycor / screen-edge-y ) * spread * steepness * .02 ] note "" dry-all end to normalize-elev ; set min to 0, max to 100 calc-measures ask patches [ ; set min to 0 set elev (elev - valley ) ; set max to screen-edge-x set elev elev * 100 / spread ] ; adjust valley, peak, spread, middle set valley 0 set peak screen-edge-x set spread screen-edge-x end to do-valley locals [ elev-east-west elev-north-south elev-meander px% py% adj-px% px-cos sweep-width meander-freq pwr ] set pwr 1 set px% pxcor / screen-edge-x ; pxcor ==> -1 .. 1 set py% 1 - ( pycor + screen-edge-y ) / screen-size-y ; pycor ==> 0 .. 1 set sweep-width .01 * meander% ; .25 + .25 * sin ( py% * 45 ) set meander-freq py% * 180 * 4 set adj-px% ( (px% + sweep-width * sin ( meander-freq ) ) ) set elev-meander (abs adj-px%) set level elev-meander ; set elev elev * ( 1 - scale) + level * elev-meander * scale end to calc-measures ; caluclate peak, valley, spread set peak max values-from patches [ elev ] set valley min values-from patches [ elev ] if peak = valley [ set peak peak + 2 set valley valley - 2 ] set middle (peak + valley) * .5 set spread abs ( peak - valley ) set vm (valley + middle) * 0.5 set pm (peak + middle) * 0.5 end to add-wall ; add wall along back / top to prevent water ; from flowing backwards wrapping from bottom, etc. ; first, caluclate peak, valley, spread set peak max values-from patches [ elev ] set valley min values-from patches [ elev ] set spread abs ( peak - valley ) ; use values to elevate back edge %10 of depth of model ask patches with [ pycor = screen-edge-y ] [ set elev peak + spread * .1 ] ; scale it up ; ask patches ; [ set elev elev * 1000 ] dry-all end to add-dam locals [ height spillway ] ; adds a dam-like structure to the map set height 1.3 * mean values-from patches [ elev ] set spillway elev-of patch 0 0 + ( height - elev-of patch 0 0 ) * .5 ask patches with [ pycor = 0 and abs pxcor < screen-edge-x / 2.0 and elev < height ] [ set elev height ] ask patch 0 0 [ set elev spillway ] dry-all end to volcano locals [ deepest peaks ] ; build an irregular, circular island ; with a shallow center lagoon ; "clear patches" cp clear-3d define-neighbors-nowrap if presets? [ set river? false set drain? false set erupt? true set source-rate 50 set altitude? true set scale .5 set shift-x .45 set shift-y .45 ] ; "create overall ring shape" ask patches [ ; get distance from center ; "doing math" set temp distancexy 0 0 ; sin wave, 0 at center, peak in middle, 0 at corners set temp3 temp * 360 / 3 / screen-edge-x ; scale as distance from edge set temp2 2 * sin ( temp * 180 / screen-edge-x ) * ( screen-edge-x - abs pxcor) / screen-edge-x * ( screen-edge-y - abs pycor) / screen-edge-y set elev screen-size-x * sin temp3 * temp2 ] ; "add random peaks and dips, repeat" repeat screen-edge-x [ ; "picking peak/pit location" set elev-of patch 0 0 (- screen-size-x) set peaks random-n-of screen-edge-x patches ; "talking to peaks" ask peaks [ ; "set temp" set temp random 2 * 2 - 1 ] ; "talking to peaks" ask peaks [ ; "set elev" without-interruption [ set elev elev + screen-edge-x * temp ] ] ] ; erode, just a bit repeat 4 [ set elev-of patch 0 0 (- screen-edge-x) diffuse-elev-nowrap ] ; add "stress ridges" ask patches [ ; get distance from center set temp distancexy 0 0 ; get angle from center ifelse temp = 0 [ set temp2 0 ] [ set temp2 ( towardsxy 0 0 + 180 ) if temp2 > 360 [ set temp2 temp2 - 360 ] ] ; set number of ridges set temp3 temp2 * screen-edge-x / 3 set elev elev + screen-edge-x * sin temp3 * sin temp * .2 ] dry-all end to rain ; add water to entire surface, using rain-rate slider ; adds depth of rain that is up to 1/10000 the height of the terrain ask patches [ set level level + rain-rate * spread * .0001 ] update-all end ; rain to rain-hard ; adds depth of rain that is up to 1/1000 height of terrain ask patches [ set level level + rain-rate * spread * .001 ] update-all end ; rain-hard to do-sources-and-drains ; adds water at top center of window if river? [ ask min-one-of patches with [ pycor = ( screen-edge-y - 1 ) ] [ elev ] [ set level level + source-rate ] ] if erupt? [ ask patch 0 0 [ set level level + source-rate ] ] if drain? [ ; removes water from bottom ask patches with [ pycor = (- screen-edge-y) ] [ set level level - volume * .1 ] ] end ; do-sources-and-drains to evaporate-all ; reduce water level by "evap rate" ; which is linear and not proportional ; as it is due to surface area, not volume if e-rate > 0 and evap? [ ask patches with [ level > elev ] [ set level level - e-rate if level < elev [ ; don't allow level to be below elev! set level elev ] ] ] end ; evaporate-all to flow-all evaporate-all ; to reduce flow bias created by natural netlogo patch code scheduling, ; only update 1 in 5 patches every turn ask patches with [ level > elev and random 3 = 0 ] [ flow-ver-2 ] ask patches [ set level level - water-out + water-in set water-out 0 set water-in 0 ] ; add water every 5 turns ;if ticks mod 5 = 0 ;[ do-sources-and-drains update-all ;] set ticks ticks + 1 if ticks > 1000000 [ set ticks 0 ] end to flow-ver-1 ; if any neighbors with lower level ; pick random one of neigbors with LOWEST level ; move 1/2 of difference in level to that neighbor ; (so both are at a level) locals [ local-min min-level extra portion max-portion ] without-interruption [ if level - elev > 0 ; if I am wet... [ set min-level min values-from (neighbors-nowrap) [ level ] if level > min-level [ set local-min random-one-of (neighbors-nowrap) with [ level = min-level ] set extra level - min-level ifelse extra < .001 ; if less than 1/1000 unit, it all flows down [ set portion extra ] [ set portion extra * .5 ; if portion is more than is here, just take all of it if portion > ( level - elev ) [ set portion level - elev ] ] ; adjust the levels set level level - portion ask local-min [ set level level + portion ] ] ] ] end to flow-ver-2 ; pick random one of neigbors with LOWEST level (lower than me!) ; move "flow-rate" (50%) of difference in level to that neighbor ; locals [ local-min min-level extra portion max-portion low-neighbors count-low-neighbors slope ] if level - elev > 0 ; if I am wet... [ set min-level min values-from (neighbors-nowrap) [ level ] if level > min-level [ set local-min random-one-of (neighbors-nowrap) with [ level = min-level ] set extra level - min-level ; set slope atan 1 extra ifelse extra < .001 ; if less than 1/1000 unit, it all flows down [ set portion extra ] [ set portion extra * flow-rate ; if portion is more than is here, just take all of it if portion > ( level - elev ) [ set portion level - elev ] ] ; adjust the levels set water-out portion set water-in-of local-min (water-in-of local-min) + portion ] ] end to label-all ; are labels requested? ifelse labels? [ ; yes. labels are requested ; ; altitude, or water depth? ifelse altitude? [ ; ; altitude / surface level ask patches [ set plabel (int (level)) ] ] [ ; show depth ask patches [ set plabel (int (level - elev)) ] ] ] [ ; no labels ; does patch 1 1 have a label? if plabel-of patch 1 1 != no-label [ ; it does, implying that all patches have labels. ; so, clear all labels ask patches [ set plabel no-label ] ] ; this would seem to be faster than clearing all the labels every cycle ] end to color-all ifelse hide-water? [ ; use elev, not level, for display, and don't show water colors ifelse false-color? [ ; color using rainbow, to show-off contours ask patches [ set pcolor 20 + 7 * scale-color gray elev valley peak ] ] [ ask patches [ set pcolor get-earth-color ] ] ] [ ; use level for display, using water colors as needed. ask patches [ set volume level - elev ] ifelse false-color? [ ; color using rainbow, to show off contours ask patches [ set pcolor 20 + 7 * scale-color gray level valley peak ] ] [ ask patches [ set pcolor get-color ] ] ] end to-report get-color-from [ agent ] locals [ result ] ask agent [ set result get-color ] report result end to-report get-color ; patch procedure ifelse volume <= 0 [ report get-earth-color ] [ report get-water-color ] end to-report get-water-color ; patch procedure locals [ scaled-color ] ifelse altitude? [ set scaled-color -4 + .8 * scale-color gray level valley peak ] [ set scaled-color 4 - .8 * scale-color gray volume 0 spread ] ifelse erupt? or volume < .01 [ report red + scaled-color ] [ report blue + scaled-color ] end to-report get-earth-color ; patch procedure ifelse elev <= vm [ report gray - 4 + .8 * scale-color gray elev valley middle ] [ ifelse elev <= pm [ report green - 4 + .8 * scale-color gray elev valley peak ] [ report brown - 4 + .8 * scale-color gray elev middle peak ] ] end to setup-3d clear-turtles ; create a turtle to use as a backdrop to hide the patches ; (instead of coloring the patches black) create-custom-backdrops 1 [ setxy 0 0 set color black + 1 set shape "box-large" set size screen-size-x ] ; these turtles, one for each patch ; show the points of elevation ask patches [ ; make a node turtle sprout 1 [ set breed nodes set my-patch patch-here set color pcolor set shape "circle-large" set size 1.0 set heading 0 set ox xcor set oy ycor set oe level ] ] render-3d end to render-3d locals [ insetx insety insetw inseth insett insetl insetb insetr] if not any? backdrops [ stop ] set insetx screen-edge-x * shift-x set insety screen-edge-y * shift-y set insetw screen-edge-x * scale set inseth screen-edge-y * scale no-display ask backdrops [ setxy insetx insety set size insetw * 2.1 ] ask nodes [ set oe level-of my-patch set color pcolor-of my-patch ; scale elevation so screen-edge-x cubic volume fits into 1/2 screen-height set pel ( oe - valley ) / screen-size-x * screen-edge-y - screen-edge-y * .5 ; spin X set px ox * cos spin + oy * sin spin ; spin and tilt Y set py (oy * cos spin - ox * sin spin) * cos tilt + pel * sin tilt ; scale and adjust center set px px * scale set py py * scale set pre-hide? ( abs px > insetw or abs py > inseth) set px px + insetx set py py + insety set hidden? pre-hide? or ( abs px > screen-edge-x or abs py > screen-edge-y ) or (slice-on? and ox != int (screen-edge-x * slice)) setxy px py ] display end to full-view set scale 1.0 set shift-x 0 set shift-y 0 set slice 0 set tilt 90 set spin 90 set spin? false set presets? false end to render-3d-no-slice locals [ insetx insety insetw inseth insett insetl insetb insetr] if not any? backdrops [ stop ] set insetx screen-edge-x * shift-x set insety screen-edge-y * shift-y set insetw screen-edge-x * scale set inseth screen-edge-y * scale no-display ask backdrops [ setxy insetx insety set size insetw * 2.1 ] ask nodes [ set oe level-of my-patch set color pcolor-of my-patch ; scale elevation so screen-edge-x cubic volume fits into 1/2 screen-height set pel ( oe - valley ) / screen-size-x * screen-edge-y - screen-edge-y * .5 ; spin X set px ox * cos spin + oy * sin spin ; spin and tilt Y set py (oy * cos spin - ox * sin spin) * cos tilt + pel * sin tilt ; scale and adjust center set px px * scale set py py * scale set pre-hide? ( abs px > insetw or abs py > inseth) set px px + insetx set py py + insety set hidden? pre-hide? or ( abs px > screen-edge-x or abs py > screen-edge-y ) setxy px py ] if size-of one-of nodes != scale * 2 [ ask nodes [ set size scale * 2 ] ] display end to clear-3d ask backdrops [ die ] ask nodes [ die ] update-all end to note [ text ] ask patch 0 0 [ ifelse text = "" [ set plabel no-label ] [ set plabel text ] ] end
View or download the complete model file (to download: right-click, save-link-as):
-- Download watershed-114.5 --