globals
[
  ;; when converting a model to use the vis projector, you would replace the experiment's
  ;; use of the following variables with their ex- shadows.
  ;; world-width, world-height, max-pxcor, min-pxcor, max-pycor, min-pycor, patches
  ;; also, unless you were careful about placing the origin exactly where it should 
  ;; be in the experimental area, find and correct any commands that refer to or
  ;; rely on, the origin's location.
  ;; you can use the patch "ex-origin" to get the identity or location of the current origin.
  ;; origin patch itself is ex-origin
  ;; origin pxcor is [ pxcor ] of ex-origin
  ;; origin pycor is [ pycor ] of ex-origin
  ex-max-pxcor ;; max and min pxcor within the experiment area 
  ex-min-pxcor
  ex-max-pycor ;; max and min pycor
  ex-min-pycor 
  ex-world-width ;; experiement world witdth
  ex-world-height ;; experiement world height
  ex-origin ;; origin patch of the experiement (placed in the center of experiment by default)
  ;; note: there is currently no facility to convert native coordinates (such as pxcor pycor, xcor, ycor)
  ;; into experiement equivalents (i.e. with respect to the ex-origin)
  ;; likewise, all world-edge crossing code must be added or corrected to
  ;; accomodate and respect the limits of the ex-patches. e.g. CAN-MOVE? will not 
  ;; work as expected, and must be replaced with 
  ;; Note that this system will not play well with the use of distance and towards,
  ;; if the intended use depended on netlogo's smart world wrapping
  ;; Note that this system will not play well with CAN-MOVE?
   
  
  
  
  ex-patches ;; patches in the experiment
  
  
  vis-border-width ;; width of border seperating vis areas
  vis-border-pcolor ;; color of border
  vis-frames ;; total number of vis windows, including main experimental windows
  vis-areas ;; list containing vis area agentsets
  vis-functions ;; list containing vis functions for each areas
  vis-frequency ;; how frequently does each visulatization need to be updated 0, 1 = alawys, 2 = every other cycle, 10 = every  10 cycles.
  border
  
  mean-elev
]

patches-own
[ ;;
  ;; vis-projector variables
  ;;
  ;; vis-source: for each vis patch, this points to the experiment patch that this vis patch
  ;; should use to calculate visualization colors.
  vis-source
  
  ;;
  ;; experiment's own variables
  ;;
  elev
  telev
]

to startup
   setup
end
   
to setup
   ca
   
   ;; first setup the experiment area shadow variables and vis-source 
   setup-vis-projector 
    
   ;; next, setup the experiment
   setup-elev
   ;; apply visualizatons for experiement innital conditions
   vis-update
end   

to setup-vis-projector
   ;; set up ex- variables
   cp
   
   set vis-border-pcolor white
   
   set vis-frames 5
   set vis-border-width 1
   
   set ex-world-height dimension - 2 * vis-border-width
   set ex-world-width ex-world-height
          
   set ex-min-pxcor min-pxcor + vis-border-width
   set ex-max-pxcor ex-min-pxcor + ex-world-width - 1
   set ex-min-pycor min-pycor + vis-border-width
   set ex-max-pycor ex-min-pycor + ex-world-height - 1
   
   set ex-origin patch 0 0
   
   
   set border patches with [ pycor <= ex-min-pycor or pycor > ex-max-pycor or
                             ( ( ( pxcor - min-pxcor ) mod (ex-world-width + vis-border-width  ) ) = 0)
                             or pxcor > ex-min-pxcor + vis-frames * (ex-world-width + vis-border-width) - vis-border-width
                           ]
   set ex-patches patches with [ not ( pxcor < ex-min-pxcor or pxcor > ex-max-pxcor or pycor < ex-min-pycor or pycor > ex-max-pycor ) ]
   
   
   let vis1 ex-patches ;; ex-patches is already in sorted order
   ;; interestingly, since [] of agentset produces a randomly ordered list,
   ;; patch-set reports an agentset with that random order (that is, the random order
   ;; becomes the inherent order of the set
   ;; if I want these agentsets to be "sorted" order I need to sort the results 
   ;; of "[] of agentset"
   let vis2 (patch-set sort [ patch-at (ex-world-width + vis-border-width) 0 ] of vis1) 
   let vis3 (patch-set sort [ patch-at (ex-world-width + vis-border-width) 0 ] of vis2)
   let vis4 (patch-set sort [ patch-at (ex-world-width + vis-border-width) 0 ] of vis3)
   let vis5 (patch-set sort [ patch-at (ex-world-width + vis-border-width) 0 ] of vis4)

   set vis-areas (list vis1 vis2 vis3 vis4 vis5)
   
   set vis-functions (list
      ;; by using a reporter, you get the following benefits:
      ;; * full debugging of function syntax
      ;; * use of temp variables and other not-an-expression tools
      ;; * ability to change function syntax without re-running startup
      ;; * less to compile at run-time
        "vis-f-1"  ;; you could name your vis-functions more discriptively, such as "vis-f-curvature" or whatever
        "vis-f-2"
        "vis-f-3"
        "vis-f-4"
        "vis-f-5"
        )
        
set vis-frequency [ 0 1 2 3 5 ]        
        
   vis-quick-ask border with [ vis-quick-color vis-border-pcolor ]
   
   (foreach vis-areas [ 27 37 47 57 67 ]
   [ vis-quick-ask ?1 with [ vis-quick-color ?2 ]
   ])
   
   ;; define source patches 
   (foreach vis-areas n-values vis-frames [ ? ]
   [ ask ?1 
     [ set vis-source patch-at (- ( ex-world-width + vis-border-width ) * ?2 ) 0
       set pcolor [ pcolor] of vis-source
     ]
   ])
   
end

to-report vis-f-1 ;; proportional to elevation
   report green - 4 + scale-color gray elev 0 1.5
end

to-report vis-f-2   ;; above/below mean
   report ifelse-value ( elev <= mean-elev )  [ sky ] [ pink ]
end

to-report vis-f-3 ;; elevation slices
   report 5 + 10 * floor (10 * elev)
end

to-report vis-f-4 ;; max-slope?
   report hsb (25.75 * scale-color gray (mean ([abs ( elev - [ elev ] of myself )] of neighbors)) 0 1 ) 240 240
end

to-report vis-f-4.5  ;; slope?
   report 70 + 40 * scale-color gray (max [ abs (elev - [ elev ] of myself ) ] of neighbors) -1 1
end

to-report vis-f-5 ;; elevation region edges
   report scale-color gray (count neighbors with [ floor ( 10 * elev) = floor [ 10 * elev ] of myself ]) 0 8 ;; edges
end





to setup-elev
   ask ex-patches  
   [ set elev random-float 1.0 ]
   repeat 4
   [ ask ex-patches [ set telev mean (fput elev [ elev ] of neighbors )]
     ask ex-patches [ set elev mean (fput telev [ telev ] of neighbors )] 
   ]
   ask ex-patches with [pxcor = pycor] [ set elev .5 ]
   let maxelev max [ elev ] of ex-patches
   let minelev min [ elev ] of ex-patches
   let spanelev maxelev - minelev
   ask ex-patches
   [ set elev (elev - minelev) / spanelev 
     set telev elev
   ]
   
end

to vis-update
   ;; a global that is calculated once per update, that one or more of the vis routines may require
   set mean-elev mean [ elev ] of ex-patches
   
   (foreach vis-areas vis-functions vis-frequency
   [ if ?3 < 2 or ( ticks mod ?3 = 0 )
     [ vis-quick-ask ?1 with [ vis-quick-color [ run-result ?2  ] of vis-source ]
     ]
   ])
end

to vis-update-vis-n
   ;; a global that is calculated once per update, that one or more of the vis routines may require
   set mean-elev mean [ elev ] of ex-patches
   
   ;(foreach vis-areas vis-functions n-values vis-frames [ ? ]
   ;[ if ?3 = vis#
   ;  [ vis-quick-ask ?1 with [ vis-quick-color [ run-result ?2  ] of vis-source ]
   ;  ]
   ;])
   vis-quick-ask (item vis# vis-areas) with [ vis-quick-color [ run-result (item vis# vis-functions)  ] of vis-source ]
   

end

to vis-quick-ask [ agentset ]
   ;; deliberately empty procedure--do not remove!
end

to-report vis-quick-color [ hue ]
   ;; reporter that takes a hue and set the pcolor as a "side-effect"
   ;; always reports false
   set pcolor hue
   report false
end

to go
   ;; no-display ;; uses on-tick updates now
   ;; do boiling-like simulation
   ask ex-patches [ set telev elev * .2 + .8 * mean [ elev ] of neighbors ]
   ask ex-patches 
   [ set elev telev + heat 
     if elev > 0 [ set elev elev * .99 ] 
     if elev > 1 [ set elev 0  if elev > 1 [ set elev 0 ] ]
   ]
   ;; either update all areas, or only one
   ifelse vis-update-all? [ vis-update ] [ vis-update-vis-n ]
   tick
   ;; display ;; uses on-tick updates now
end
   
to-report ex-can-move? [ stride ] 
   ;; reports true if the current turtle can move fowards
   ;; along it's current heading the given distance and remain 
   ;; inside the world.
   ;; THIS IS NO-WRAP ONLY
   let nx xcor + dx * stride
   let ny ycor + dy * stride
   report ( not (nx < ex-min-pxcor or nx > ex-min-pycor or ny < ex-min-pycor or ny > ex-min-pycor))
end
   
   
   
@#$#@#$#@
GRAPHICS-WINDOW
10
210
1523
550
-1
51
3.0
1
10
1
1
1
0
0
0
1
-51
449
-51
51
1
1
1
ticks

CC-WINDOW
5
564
1532
659
Command Center
0

BUTTON
10
50
70
83
NIL
setup
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL

BUTTON
10
90
70
123
NIL
go
T
1
T
OBSERVER
NIL
NIL
NIL
NIL

SLIDER
75
90
170
123
heat
heat
0
.5
0.015
.001
1
NIL
HORIZONTAL

SLIDER
10
10
170
43
dimension
dimension
41
101
51
10
1
NIL
HORIZONTAL

SWITCH
11
130
171
163
vis-update-all?
vis-update-all?
1
1
-1000

TEXTBOX
180
10
800
113
1. Set size of experiment area using dimension slider. For example, selecting 31 provides a 31 x 31 patch experiment area.\n\n2. Press Setup.\n\nThe initial \"landscape\" generator runs. All visualization areas are updated.\n\n3. Press go. The \"boiling\" simulation runs.
11
0.0
1

SLIDER
10
170
170
203
vis#
vis#
0
vis-frames - 1
2
1
1
NIL
HORIZONTAL

TEXTBOX
182
176
596
194
With vis-update-all? off, use the vis# slider to select a single visualization to update.
11
0.0
1

TEXTBOX
180
129
742
157
The vis-update-all? switch controls whether all vis areas are updated, or only the selected vis (vis#).\nIn update-all mode, vis update frequency is determined by the vis-frequency variable.
11
0.0
1

@#$#@#$#@
WHAT IS IT?
-----------
A demonstration of a method for obtaining multiple visualizations of the same data using patches.

As a side-effect, also shows a method of using only a variably-sized portion of the patches as the experiment area of a model.

HOW IT WORKS
------------
By limiting the experiment to a portion of the patches, and expanding the view to provide extra patches just for visualization, visualizations (i.e. pcolors) calculated by the experiment area can be "projected" onto the extra patches.

CREDITS AND REFERENCES
----------------------
By James P. Steiner
See more at http://www.turtlezero.com
@#$#@#$#@
default
true
0
Polygon -7500403 true true 150 5 40 250 150 205 260 250

@#$#@#$#@
NetLogo 4.0
@#$#@#$#@
@#$#@#$#@
@#$#@#$#@
@#$#@#$#@
@#$#@#$#@
default
0.0
-0.2 0 0.0 1.0
0.0 1 1.0 0.0
0.2 0 0.0 1.0
link direction
true
0
Line -7500403 true 150 150 90 180
Line -7500403 true 150 150 210 180

@#$#@#$#@
