powered by NetLogo

view/download model file: YevgeniyCurve.nlogo

WHAT IS IT?

This displays a sequence of curves, each starting at (0,0) and ending at (0,0), that, in the limit, will pass through every point of the square.


CREDITS AND REFERENCES

Dec. 2011
Yevgeniy Rudoy: developed the curve and the proof of its space-filling property.
Peter Brooks: developed this visualization.


PROCEDURES

globals[
  level
  curr-path
  drawer
  segment-time
]

to setup
  ; origin is at (1 - min-pxcor, 1 - min-pycor)
  ; upper-left corner is at (max-pxcor - 1, max-pycor - 1)
  ca
  set level 0
  set curr-path [[0 0] [1 1] [0 0]]
  crt 1 [
    set drawer self
    set color white
  ]
  set segment-time 1
end

to-report world-nl [world-point]
  ; Converts model (or world) coordinates (0,0) - (1,1) to netlogo coordinates
  let x item 0 world-point
  let y item 1 world-point
  let nl-x (1 + min-pxcor) + x * (max-pxcor - min-pxcor - 2)
  let nl-y (1 + min-pycor) + y * (max-pycor - min-pycor - 2)
  report (list nl-x nl-y)
end

to go
  DrawPath
  wait .5
  if level >= max-level
  [  ct
     stop
  ]
  set level level + 1
  CalcNewPath
end

to DrawPath
  cd
  let l (length curr-path) - 1
  let i 0
  while [i < l]
  [  let p-start item i curr-path
     let p-end item (i + 1) curr-path
     ask drawer
     [  let nl-start world-nl p-start
        let nl-end world-nl p-end
        setxy (item 0 nl-start) (item 1 nl-start)
        facexy (item 0 nl-end) (item 1 nl-end)
        pd
        setxy (item 0 nl-end) (item 1 nl-end)
        pu
     ]
     if segment-time / l > .001
     [  wait segment-time / l ]
     set i i + 1
  ]
end

to CalcNewPath
  ; calculates a new path, based on the previous path using a little vector algebra 
  let new-path [[0 0]]
  let p-start [0 0]
  let l (length curr-path) - 1
  let i 1
  while [i <= l]
  [  let p-end (item i curr-path)
     let mid-x .5 * ((item 0 p-end) - (item 0 p-start))
     let mid-y .5 * ((item 1 p-end) - (item 1 p-start))
     let cross-prod -1 ^ level
     let trial-x 0 - mid-y
     let trial-y mid-x
     let z trial-x * mid-y - mid-x * trial-y
     if cross-prod * z < 0
     [  set trial-x mid-y
        set trial-y 0 - mid-x
     ]
     let new-mid-x (item 0 p-start) + mid-x + trial-x
     let new-mid-y (item 1 p-start) + mid-y + trial-y
     set new-path fput (list new-mid-x new-mid-y) new-path
     set new-path fput p-end new-path
     
     set i i + 1
     set p-start p-end
  ]
  set curr-path reverse new-path
end