Light sandbox
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
WHAT IS IT?
This model supports a drawing style interface for "sketching" up representations of the interaction of light and matter. In particular, the user can explore phenomena related to light rays, shadows, mirrors, light intensity, color mixing.
In this model, the user can adjust various light sources (up to 3), by moving their location, turning them on or off, adjusting the intensity of light and the color of the light source. Each light source generates "light particles" that travel away from the light source and interact with different types of matter. The user can add (by sketching with the mosue) new sections of "rough" walls, which can either scatters or absorb the light that hits it or the user can add "smooth" mirrored surfaces which reflect the light that hits it.
This model enables students to either explore various pre-defined scenarios (e.g. a single light source and a wall that creates a shadwo), or draw a new model of a real world system and then test that model. A wide range of real world systems can be modeled with this simple interface (e.g. two flashlights and a single object creating various shadows, how distance of a light source to an object affects the size of the shadow, or how colors of light additively mix).
HOW IT WORKS
The light rays are modeled as particles that trace out their path as they move.
The exact way light particles move is as follows:
- A light particle moves in a straight line without changing its speed, unless it hits a wall.
- Reflective surfaces (mirrors) cause the light particle to bounce off in a symmetrical "V" shaped path
The exact way light intensity is determined at a patch is as follows:
- Each time a light particle is in a patch it adds its light value (red, green, blue, or all) to the patch.
- When light has passed through all patches the patch renders the intensity and color of the light at that location by using the rgb primative on these accumulated light values at the patch.
HOW TO USE IT
Buttons:
SETUP - sets up the initial conditions set on the sliders.
GO/STOP - runs and stops the model.
Sliders:
RAYS-PER-LIGHT-SOURCE - sets the number of light particles emiited from each light source.
REFLECTIONS-PER-PARTICLE (non functional as of now)
Switches:
Choosers:
SCENARIO - explore some precreated scenarios by chaging this setting or set to "create my own scenario" to use the mouse to employ different actions (through drawing with the mouse cursor) in the WORLD & VIEW
MOUSE SETTING - describes what action the mouse will perform when the mouse button is pressed down when the cursor is in the WORLD & VIEW.
THINGS TO NOTICE
The mouse interaction can be used while the model is running as well as when it is stopped.
THINGS TO TRY
Create a model of howan overhead projector uses a mirror to project onto a screen.
Create a model of how 3 light sources: red, green, and blue light can combine to make white light.
Create a model of how an eclipse creates a penumbra (use multiple light sources to simulate the larger size of the sun).
RELATED MODELS
CREDITS AND REFERENCES
Comments and Questions
globals [ tick-delta ;; how much we advance the tick counter this time through max-tick-delta ;; the largest tick-delta is allowed to be init-avg-speed init-avg-energy ;; initial averages avg-speed avg-energy ;; current average avg-energy-green avg-energy-orange avg-energy-purple photon-size toggle-red-state toggle-green-state min-photon-energy max-photon-energy photons-to-add clear-drawing-flag new-objects? old-switch-state first-source-selected photon-model count-detector-1 count-detector-2 ] breed [ photons photon ] breed [ detectors detector ] breed [ walls wall ] breed [ transparent-solids transparent-solid ] breed [ sources source ] breed [ flashes flash ] breed [ erasers eraser ] breed [ arrowheads arrowhead ] photons-own [ energy ;; photons info last-collision color-type last-patch bounces ] walls-own [gate? outside-system?] detectors-own [id] patches-own [ red-absorbed green-absorbed blue-absorbed] sources-own [selected?] to setup ;; (for this model to work with NetLogo's new plotting features, ;; __clear-all-and-reset-ticks should be replaced with clear-all at ;; the beginning of your setup procedure and reset-ticks at the end ;; of the procedure.) clear-all set count-detector-1 0 set count-detector-2 0 set photon-size 1.0 set max-tick-delta 0.02 set new-objects? false set photons-to-add 2 set clear-drawing-flag false set photon-model "wavefront-of-rays" set-default-shape flashes "square" set-default-shape walls "wall" set-default-shape erasers "eraser" set-default-shape arrowheads "default" set min-photon-energy 0 set max-photon-energy 10000 ;;(.5 ) * ( max-dist-in-tick-delta / max-tick-delta ) ^ 2 create-erasers 1 [set hidden? true set size 3 set color gray - 1] setup-scenarios set old-switch-state light-A make-box make-light-sources create-detectors 1 [set color orange set shape "circle" set size 1 setxy 20 34 set id 1] create-detectors 1 [set color violet set shape "circle" set size 1 setxy 40 40 set id 2] set init-avg-speed avg-speed set init-avg-energy avg-energy check-detectors reset-ticks end to check-detectors ask detectors [ if id = 1 [set count-detector-1 count photons-here] if id = 2 [set count-detector-2 count photons-here] ] end to go ifelse mouse-down? [mouse-action] [ check-for-new-toys ;; activate-light-switch ask photons [move interact-with-wall ] ask erasers [set hidden? true] ] if count photons = 0 [recolor] tick check-detectors end to interact-with-wall ;;if random 100 > %-of-scattering [absorb-into-wall die] if bounces > 1 [die] scatter end to emit-light-from-light-source ask patches [reset ] if photon-model = "random-rays" [ ifelse light-A [ if count photons < rays-per-light-source [ repeat random 4 [ask sources [make-photons]] ] ] [clear-drawing ask photons [die] ] ] if photon-model = "wavefront-of-rays" [ ask sources [make-photon-batch] ;; ifelse light-A = true and (old-switch-state = false or count photons = 0) [ ;; set old-switch-state true ;;ask sources [make-photon-batch] ;; ] ;; [set old-switch-state light-A] ] end to check-for-new-toys if new-objects? [ ask photons [die] ;; clear-drawing set new-objects? false ] end to absorb-into-wall ask walls-here [ set red-absorbed red-absorbed + (10 / rays-per-light-source) set green-absorbed green-absorbed + (10 / rays-per-light-source) set blue-absorbed blue-absorbed + (10 / rays-per-light-source) ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WALL AND PATCH INTERACTION;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to add-lighting-to-patch let color-of-light color ;; show color-of-light ask patch-here [ ;; if color-of-light = 9.9 [ set red-absorbed red-absorbed + (light-source-intensity-A * 90 / rays-per-light-source) set green-absorbed green-absorbed + (light-source-intensity-A * 90 / rays-per-light-source) set blue-absorbed blue-absorbed + (light-source-intensity-A * 90 / rays-per-light-source) ; ] ;;if color-of-light = 15 [ ;; set red-absorbed red-absorbed + (light-source-intensity-A * 900 / rays-per-light-source) ;; ] ;; if color-of-light = 55 [ ;; set green-absorbed green-absorbed + (light-source-intensity-A * 900 / rays-per-light-source) ;; ] ;; if color-of-light = 105 [ ;; set blue-absorbed blue-absorbed + (light-source-intensity-A * 900 / rays-per-light-source) ;; ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;LIGHT photon MOVEMENT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to bounce ;; photons procedure ;; get the coordinates of the patch we'll be on if we go forward 1 let bounce-patch nobody let bounce-patches nobody let hit-angle 0 let this-patch patch-here let new-px 0 let new-py 0 let visible-wall nobody set bounce-patch min-one-of walls in-cone ((sqrt (2)) / 2) 180 with [myself != this-patch] [distance myself ] if bounce-patch != nobody [ set new-px [pxcor] of bounce-patch set new-py [pycor] of bounce-patch set visible-wall walls-on bounce-patch if any? visible-wall with [not hidden?] [ set hit-angle towards bounce-patch ifelse (hit-angle <= 135 and hit-angle >= 45) or (hit-angle <= 315 and hit-angle >= 225) [set heading (- heading) ] [set heading (180 - heading) ] ]] end to scatter ;; turtle procedure let this-patch patch-here let bounce-patch min-one-of walls in-cone ((sqrt (2)) / 2) 180 with [myself != this-patch] [distance myself ] if bounce-patch != nobody [ let new-px [pxcor] of bounce-patch let new-py [pycor] of bounce-patch let visible-wall walls-on bounce-patch if any? visible-wall with [not hidden?] [ let hit-angle towards bounce-patch set bounces bounces + 1 if light&matter = "absorb some / scatter some" [set heading random 360 fd .2] if light&matter = "absorb all" [die] ifelse (hit-angle <= 135 and hit-angle >= 45) or (hit-angle <= 315 and hit-angle >= 225) [ if light&matter = "reflect all" [ set heading (- heading) fd .2 ] if light&matter = "absorb 50% / reflect 50%" [ ifelse random 2 = 0 [set heading (- heading) fd .2 ] [die] ] ] [ if light&matter = "reflect all" [ set heading (180 - heading) fd .2 ] if light&matter = "absorb 50% / reflect 50%" [ ifelse random 2 = 0 [set heading (180 - heading) fd .2 ] [die] ] ] ] ] if any? walls-here or bounces > 1 [die] end to move ;; photons procedure let old-patch last-patch if not any? transparent-solids-here [fd .2] if any? transparent-solids-here [fd (.2 * speed-of-light-through-solid)] add-lighting-to-patch set last-patch patch-here end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; mouse interaction procedures ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to mouse-action let snap-xcor 0 let snap-ycor 0 let orig-xcor 0 let orig-ycor 0 let eraser-window-walls nobody let eraser-window-photons nobody let eraser-light-sources nobody let selected-eraser-light-source nobody ifelse mouse-down? [ set orig-xcor mouse-xcor set orig-ycor mouse-ycor set snap-xcor round orig-xcor set snap-ycor round orig-ycor clear-drawing if mouse-setting = "move light source" and any? sources with [selected?] [ask sources with [selected?] [setxy mouse-xcor mouse-ycor]] ask patches with [pxcor = snap-xcor and pycor = snap-ycor] [ set eraser-window-walls walls-on neighbors set eraser-window-walls eraser-window-walls set eraser-window-photons photons with [distance myself < 2] set eraser-light-sources sources with [distance myself < 2] if mouse-setting = "draw container wall" [ draw-container-wall ] if mouse-setting = "draw transparent solid" [ draw-transparent-solid ] if mouse-setting = "big eraser" [ set new-objects? true ask erasers [ set hidden? false set shape "eraser" setxy orig-xcor orig-ycor ] ask eraser-window-walls [die] ask eraser-window-photons [die] ] if selected-eraser-light-source = nobody and any? eraser-light-sources [ set selected-eraser-light-source one-of eraser-light-sources if mouse-setting = "move light source" [ set new-objects? true ask selected-eraser-light-source [setxy mouse-xcor mouse-ycor set selected? true] set clear-drawing-flag true ask photons [die] ] ] ] ] ;; 2nd part of ifelse block [ ask erasers [set hidden? true] set selected-eraser-light-source nobody ask sources [set selected? false] ] end to draw-container-wall set new-objects? true ask walls-here [die] ask transparent-solids-here [die] sprout 1 [ set breed walls set color white set gate? false ] end to draw-transparent-solid set new-objects? true ask walls-here [die] ask transparent-solids-here [die] sprout 1 [ set breed transparent-solids set color [255 255 255 50] set size 1 set shape "solid"] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; photon speed and flash visualization procedures ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to recolor ;;if any? walls-here with [not absorb?] [] ifelse show-light-intensity-in-space? [ask patches [set pcolor rgb red-absorbed green-absorbed blue-absorbed ]] [ask patches [set pcolor black ]] end to reset set red-absorbed 0 set green-absorbed 0 set blue-absorbed 0 set pcolor black end to color-photon-and-link let this-link my-out-links let this-color-type color-type set color this-color-type ask this-link [set color this-color-type] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; initialization procedures ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to make-box ask patches with [(pycor = min-pycor or pycor = max-pycor or pxcor = min-pxcor or pxcor = max-pxcor) ] [ sprout 1 [set breed walls set gate? false set color gray - 1 ] ] end to make-light-sources create-sources 1 [ initialize-bulb setxy 5 30 set label "A" ifelse light-A [set hidden? false] [set hidden? true] ] create-sources 1 [ initialize-bulb setxy 25 25 set label "B" ifelse light-B [set hidden? false] [set hidden? true] ] create-sources 1 [ initialize-bulb setxy 30 30 set label "C" ifelse light-C [set hidden? false] [set hidden? true] ] end to initialize-bulb set selected? false set heading 0 set shape "bulb" set size 2 set color white end to make-photons hatch 1 [ set energy 100 rt random 360 setup-photons ;;setxy ([xcor] of parent-bulb) ( [ycor] of parent-bulb) ] end to make-photon-batch let parent-source self let angle-counter 0 let source-A false let source-B false let source-C False if (label = "A" and light-A) [set source-A true] if (label = "B" and light-B) [set source-B true] if (label = "C" and light-C) [set source-C true] if (source-A or source-B or source-C) [ hatch rays-per-light-source [ if ((source-A and light-A-color = "white") or (source-B and light-B-color = "white") or (source-C and light-C-color = "white")) [set color white] if ((source-A and light-A-color = "red") or (source-B and light-B-color = "red") or (source-C and light-C-color = "red")) [set color red] if ((source-A and light-A-color = "green") or (source-B and light-B-color = "green") or (source-C and light-C-color = "green")) [set color green] if ((source-A and light-A-color = "blue") or (source-B and light-B-color = "blue") or (source-C and light-C-color = "blue")) [set color blue] set label "" rt angle-counter set angle-counter angle-counter + (360 / rays-per-light-source) setup-photons setxy ([xcor] of parent-source) ( [ycor] of parent-source) ] ] end to setup-photons ;; photons procedure set breed photons set shape "arrow head" set size photon-size set last-patch patch-here set color [255 255 255 50] set bounces 0 ifelse show-rays? [pendown] [penup] end to setup-scenarios if scenario = "light rays forming a simple shadow" [ set light-A true set light-B false set light-C false set show-rays? true set show-light-intensity-in-space? false set rays-per-light-source 180 ask patches with [pxcor = 14 and abs pycor < 5] [] ] if scenario = "shadow from single light" [ set light-A true set light-B false set light-C false set show-rays? false set show-light-intensity-in-space? true set rays-per-light-source 720 ask patches with [pxcor = 14 and pycor < 5 and pycor > -10] [] ] if scenario = "shadows from 3 lights" [ set light-A true set light-B true set light-C true set show-rays? false set show-light-intensity-in-space? true set rays-per-light-source 720 ask patches with [abs pxcor = 14 and pycor < 5 and pycor > -10] [] ask patches with [abs pxcor <= 1 and pycor < 15 and pycor > 5] [] ] end to clear-background clear-drawing ask patches [ if not any? walls-here [set pcolor black] ] display end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;REPORTERS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to-report limited-photon-energy let limited-energy energy if limited-energy > max-photon-energy [set limited-energy max-photon-energy] if limited-energy < min-photon-energy [set limited-energy min-photon-energy] report limited-energy end
There is only one version of this model, created over 6 years ago by Michael Novak.
Attached files
No files
This model does not have any ancestors.
This model does not have any descendants.