;; SUMMARY ;;;; A simple simulation of falling particles reacting to obstacles. ;; COPYRIGHT & LICENSE ;;;; Copyright (C) 2005 James P. Steiner ;;;; Some Rights Reserved. ;;;; Creative Commons Attribution-NonCommercial-ShareAlike License v. 2.0. ;;;; Visit http://creativecommons.org/licenses/by-nc-sa/2.0/ for more information. globals [ last-drop ; use by do-mouse mode ; used by do-mouse top-row ; used by do-fill drain-row ; used by do-drain field ; the patches that are not border patches border ; the border patches ] breeds [ balls ; balls are the particles ] patches-own [ void? ; true means patch is empty, and not an obstacle ] to startup setup end to setup ca ask patches [ set void? true ] reset-screen-regions set top-row patches with [ pycor = screen-edge-y ] set drain-row patches with [ pycor = (- screen-edge-y) + 1 ] make-funnel make-splotches make-pins end to go ; if using mouse, all else pauses ifelse active-mouse? and mouse-down? [ do-mouse ] [ set mode 0 ; reset draw / erase mode ; evaluate the run-time effect switches if drain? [ do-drain ] if fill? [ do-fill ] ; balls fall without-interruption [ ask balls [ do-fall ] ] ] end to define-field set field patches with [ abs pxcor < screen-edge-x and pycor > (- screen-edge-y) ] end to define-border set border patches with [ abs pxcor = screen-edge-x or pycor = (- screen-edge-y) ] end to-report field-not-defined? report not is-patch-agentset? field end to-report border-not-defined? report not is-patch-agentset? border end to define-screen-regions if field-not-defined? [ define-field ] if border-not-defined? [ define-border ] end to reset-screen-regions define-screen-regions clear-field set-border end to clear-field ask balls [ pop ] ask field [ clear-grid ] end to set-border ask border [ set void? false set pcolor sky ] end to do-drain if random 100 < drain-rate [ let drain-balls balls with [ pycor = (- screen-edge-y) + 1 ] if any? drain-balls [ ask random-one-of drain-balls [ pop ] ] ] end to do-fill if random 100 < fill-rate [ let open-patches top-row with [ void? = true ] if any? open-patches [ ask random-one-of open-patches [ make-ball] ] ] end to make-ball ; patch procedure sprout 1 [ set breed balls set shape "circle" set heading 180 set void? false let new-color who if new-color mod 10 <= 2 [ set new-color new-color + 2 ] if new-color mod 10 >= 8 [ set new-color new-color + 4 ] set color new-color ] end to do-fall let below patch-at 0 -1 let beside patches at-points [ [ -1 0 ] [ 1 0 ] ] let above patch-at 0 1 ; if open space directly below, fall straight down ifelse void?-of below = true [ set void? true set ycor ycor - 1 set void? false ] ; otherwise, if patch at left or right is clear, ; and patch below that is clear as well, fall down to the side [ set beside beside with [ void? = true and void?-of patch-at 0 -1 = true ] ifelse any? beside [ set beside random-one-of beside set void? true set xcor pxcor-of beside set ycor pycor - 1 set void? false ] ; otherwise, if patch above IS a ball, and any side patch is open, pick a direction, and go that way [ set beside beside with [ void? = true ] ifelse ( void?-of above = false and ( value-from above [ any? balls-here ] = true ) and ( any? beside ) ) [ set beside random-one-of beside set void? true set xcor pxcor-of beside set void? false ] ; otherwise, if patch above is (non ball) obstacle, and exactly one side is open, roll that way [ if ( void?-of above = false and (value-from above [ not any? balls-here ] = true ) and any? beside with [ void? = true ] and any? beside with [ not void? = true ] ) [ set beside one-of beside with [ void? = true ] set void? true set xcor pxcor-of beside set void? false ] ] ] ] end to randomize-order if any? balls [ ask random-one-of balls [ hatch 1 [set color color + 1] die ] ] end to do-mouse let here patch-at mouse-xcor mouse-ycor if last-drop != here [ set last-drop here ask here [ ifelse draw-mode? [ if (mode != 2 and pcolor = black) or (mode = 1 and pcolor != blue ) [ let nib here if fat-pen? [ set nib (field in-radius-nowrap 1.5 ) with [ void? = true or any? balls-here ] ] ask nib [ ask balls-here [ pop ] set-grid ] set mode 1 ] if (mode != 1 and pcolor = gray ) or (mode = 2 and pcolor != blue ) [ let nib here if fat-pen? [ set nib (field in-radius-nowrap 1.5 ) with [ void? = false and (pcolor = gray or any? balls-here) ] ] ask nib [ ask balls-here [ pop ] clear-grid ] set mode 2 ] ] [ if not any? balls-here and void? = true [ make-ball ] ] ] ] end to clear-obstacles without-interruption [ ask patches with [ void? = false and pcolor = gray ] [ clear-grid ] ] end to clear-particles without-interruption [ ask balls [ pop ] ] end to make-funnel let funnel-tip patch 0 (int (screen-edge-y * .25)) ask field with [ pycor < ( screen-edge-y * .75 ) and self != ( funnel-tip ) and ( towards funnel-tip = 135 or towards funnel-tip = 225 ) ] [ set-grid ] ask field with [ pycor = int( screen-edge-y * .75 ) and abs pxcor > (screen-edge-x * .25) ] [ set-grid ] ask funnel-tip [ clear-grid ] end to make-splotches let number 5 let min-size screen-edge-x / 8 ask random-n-of number field with [ pycor < screen-edge-y * -.33 and pycor > screen-edge-y * -.75 ] [ ask field in-radius-nowrap (min-size + random min-size ) [ set-grid ] ] end to make-pins ask field with [ pycor >= screen-edge-y * -.2 and pycor <= screen-edge-y * .2 and (pycor + 1) mod 2 = 0 and floor (pxcor + pycor / 2) mod 2 = 0 ] [ set-grid ] end to clear-grid set pcolor black set void? true end to set-grid set pcolor gray set void? false end to pop hide-turtle set void? true die end @#$#@#$#@ GRAPHICS-WINDOW 197 10 397 415 17 34 5.43 1 10 1 1 1 0 1 1 1 CC-WINDOW 5 429 406 524 Command Center 0 BUTTON 9 10 75 43 NIL setup\n NIL 1 T OBSERVER T S BUTTON 82 10 145 43 NIL go T 1 T OBSERVER NIL G SWITCH 33 81 144 114 draw-mode? draw-mode? 0 1 -1000 MONITOR 44 298 136 347 grains count balls 3 1 SWITCH 9 47 144 80 active-mouse? active-mouse? 0 1 -1000 SWITCH 9 154 99 187 drain? drain? 0 1 -1000 SWITCH 100 154 190 187 fill? fill? 0 1 -1000 SLIDER 9 227 179 260 drain-rate drain-rate 0 100 40 1 1 NIL SLIDER 9 261 179 294 fill-rate fill-rate 0 100 45 1 1 NIL BUTTON 9 193 92 226 NIL clear-particles NIL 1 T OBSERVER NIL NIL SWITCH 54 115 144 148 fat-pen? fat-pen? 0 1 -1000 BUTTON 93 193 179 226 NIL clear-obstacles NIL 1 T OBSERVER NIL NIL @#$#@#$#@ =WHAT IS IT?= This is a simple simulation of falling particles reacting to obstacles. =HOW IT WORKS= Particles fall, pile-up, and flow over each other and obstacles, according to a collection of simple rules =HOW TO USE IT= ==Click Setup.== This sets of the field and draws some default obstacles ==Click Go.== This starts particles falling. If |active-mouse?| is on, you can draw particles or obstacles. If |draw-mode?| is on, then the mouse will add and erase obstacles, otherwise, the mouse will add particles. The |fat-pen?| switch causes the mouse to draw or erase a larger block of obstacles at once. If |fill?| is on, new particles are created at the top. If |drain?| in on, particles are removed from the bottom. The sliders |fill-rate| and |drain-rate| control how quickly particles are added and removed. =THINGS TO TRY= * Draw in various configurations of obstacles. * Draw an hourglass. * Draw a cascade fountain. * Draw a waterfall. * Draw conduits and pipes. =EXTENDING THE MODEL= ==Add pressure== There is no sense of "pressure" on the particles, so particles will not flow horizontally (except in certain special cases, like along one-unit-high channels) or up-hill, like water finding a level. So, add "pressure" : a force that can cause particles to move because of the state of particles that may be quite far away. ==Add acceleration== Falling objects accelerate as they fall. That is, they gain speed. In this model, the particles fall at a steady speed. Change the model so that the particles speed up as they fall. Careful! You need to make sure the particles don't skip past the obstacles, other particles, or the "bottom"! ==Add "bounce"== Particles like sand and ball-bearings don't usually just fall, land, and sit there. They often bounce when they land. In this model, particles do not bounce. Should particles landing on "sloped" surfaces bounce at a particular angle? Would it be just as well for particles to bounce at a random angle? ==Consider other "realistic effects"== This brings us to the question: How much realism is "enough"? That is, what is the least-sophisticated our model can be while still providing useful results? Is it possible for too much realism to reduce the effectivness of a model or to damage the results? ==Implement the obstacles as turtles== The obstacles are patches. What if they were turtles? How could the model's code be optimized? Would it be faster or slower? What would that let you do? ==Implement anti-particles== What if there was another breed of particles that followed the same rules, but in reverse? That is, they fall *up*. How would the two kinds of particles interact? What if two particles (the particle and an anti-particle) wanted to occupy each-other's spots? Can they swap places? How would that change things? ==Make a game== You can use this model as the basis for a game, like a Pachinko machine, or a game where the player must insert (or remove) obstacles to direct the particles into a goal. There may be un-removable obstacles, or un-fillable space that the player must work around. Perhaps a suite of special obstacles that add, destroy, move, or re-direct particles could be involved. Another game may involve the interaction of particles and anti-particles. @#$#@#$#@ default true 0 Polygon -7500403 true true 150 5 40 250 150 205 260 250 circle false 0 Circle -7500403 true true 35 35 230 @#$#@#$#@ NetLogo 3.0.2 @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ @#$#@#$#@