Light sandbox

No preview image

1 collaborator

Default-person Michael Novak (Author)

Tags

(This model has yet to be categorized with any tags)
Visible to everyone | Changeable by the author
Model was written in NetLogo 6.0.4 • Viewed 1845 times • Downloaded 26 times • Run 0 times
Download the 'Light sandbox' modelDownload this modelEmbed this model

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:

  1. A light particle moves in a straight line without changing its speed, unless it hits a wall.
  2. 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:

  1. Each time a light particle is in a patch it adds its light value (red, green, blue, or all) to the patch.
  2. 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

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

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.