This page was automatically generated by NetLogo 5.0.3.

The applet requires Java 5 or higher. Java must be enabled in your browser settings. Mac users must have Mac OS X 10.4 or higher. Windows and Linux users may obtain the latest Java from Oracle's Java site.

powered by NetLogo

view/download model file: slinky.nlogo


This is a dynamic model of a “slinky”. The “slinky” is a chain of nodes connected by springs, and pulled down by gravity. There is also “damping” in the system (a “friction” force, opposite to (and linear in) velocity).

This model was partly inspired by this video: .

(but also by the desire to explore dynamical systems and numerical solvers … )

Some aspects of this model (especially the basic form of the Runge Kutta solver) came from the Bouncing Ball netlogo model:


This model uses a 4th order Runge Kutta numerical solver for movement of the nodes. There are several modes:

Default: One node (the top) is fixed, the others are free to move. The moving nodes are pulled down by a fixed gravitational force. They also experience forces caused by “springs” attaching them to other nodes. These “springs” have a rest-length, and exert a (linear) force on their ends, trying to return to their rest-length.

Do-drop: This releases the top node, so they all fall (if gravity is on).

Drive: In this mode, the top node is “driven” – either oscillating up and down, or rotating in a circle.

There is also a “ground” at the bottom. If nodes hit the ground, they bounce back up (elastic collision). If nodes go off screen, they become invisible, but stay active in the model. The model wraps horizontally, but not vertically …


Click on setup to initialize the slinky. Click on go to start the model. While the model is running, you can change the various parameters. You also can grab a node with the mouse and move it around.

The plot shows the y coordinates of the top node, the bottom node, and the center-of-mass of the system.

You can slow things down to see better what is happening by using the Interface “speed” slider.


This is a fairly simple model.


Grab nodes with the mouse while the model is running. Change the various parameter settings while the model is running.

Movies: (Use this with local models, not via the web) You can make a sequence of images for creating a movie of the model. To do this, type ‘set filename “movie”’ in the command center immediately after clicking “setup”. When the model sees the filename has been set to a non-null value while running (“go”), it will take a picture every step of the model. The filenames will look like movie0001.png movie0002.png … etc. You can stop the process by clicking on “go” when you have enough images. Alternatively, the model can be stopped by “set stoptick 100” or some similar value, again using the command center.


Go for it! :-)

I’m hoping to add a “pendulum” mode, but not yet …


Nothing particularly special – uses “links” …


As noted above, the “Bouncing Ball”


There are a variety of (somewhat) related physics applets available here:


globals [x-max y-max diam filename
  g b k dt xzero yzero]

  x y vx vy ax ay xtemp ytemp vxtemp vytemp
  kx1 kx2 kx3 ky1 ky2 ky3 jx1 jx2 jx3 jy1 jy2 jy3

to setup  ; Setup the model for a run, build a plot.
  ;; (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.) ..
  set xzero 0
  set yzero y-max - 3
  ask turtle 0 [ setxy 0 yzero ]

to go 

  set k spring-force
  set b mydamping
  set g mygravity
  ;; Now go use Runge-Kutta
  ifelse (do-drop)
     [ drop-slinky ]
     [ ifelse (drive)
       [driven ]
  if filename = 0 [setup] ; an attempt to work even tho user forgets setup
  ; this allows us to grab a node and drag it . . .
  let t 0
  if mouse-down? [
    set t closest-xy mouse-xcor mouse-ycor turtles ;
    while [mouse-down?] [
      ask t [
        set x mouse-xcor
        set y mouse-ycor
        setxy x y
  ; if (ticks = 1000) [stop] ; stop after a while, if you want . . .

to setup-globals  ; separate procedure for setting globals
  set diam 1.5
  set x-max max-pxcor - (diam / 2) + 1   ; 0.5
  set y-max max-pycor - (diam / 2) + 1   ; 0.5
  set filename "" ; change to collect images (or just use command center after setup)
  set-default-shape turtles "circle"
  set dt 0.01  ; step size for Runge Kutta

to setup-patches
    ;   make the ground green
  ask patches [ if pycor < (5 + min-pycor) [set pcolor green ]]

to setup-turtles
  crt number-of-nodes [
    ifelse (who = 0)
       [set color blue]
       [ifelse (who = number-of-nodes - 1)
          [set color magenta]
          [set color yellow]
    set label-color black
    set size diam
;    set label who
    set vx 0
    set vy 0
    set ax 0
    set ay 0
    set x 0
    set y (y-max - who - 5)  ; start them out stacked . . .
    setxy x y

to setup-slinky  ; Build the slinky
  ask turtles with [(who > 0)] [ 
    let mywho who
    ask self [
      connect-edge turtle (mywho - 1)

; find new velocity and position of nodes using 4th order Runge Kutta. 
to update-coordinates
      let kx4 vx
      let ky4 vy
      ;   here is the first place where we put in the differential equation
      ;     we are solving
      ;     ax, ay is the acceleration from the springs (neighbors),
      ;     - b * vx, -b * vy is damping (friction) -- a simple model
      ;         where damping is linear in velocity
      ;     -g is the force of gravity (constant, - y direction . . .)
      let jx4 (ax - b * vx )
      let jy4 (ay - b * vy - g) 
      set vx vxtemp + (dt / 6)*(jx1 + (2 * jx2) + (2 * jx3) + jx4)
      set vy vytemp + (dt / 6)*(jy1 + (2 * jy2) + (2 * jy3) + jy4)
      set x  xtemp + (dt / 6)*(kx1 + (2 * kx2) + (2 * kx3) + kx4)
      set y  ytemp + (dt / 6)*(ky1 + (2 * ky2) + (2 * ky3) + ky4)
      set ax 0
      set ay 0
; If a node found below the green ground we give it positive velocity.
; This corresponds to a perfectly elastic collision with the ground.
      if y < 5 + min-pycor [ set vy abs vy  ]

;; Here we hide nodes that have moved off screen. They are still part of the simulation, and
;; if they return on screen they become visible again.
      ifelse (y > max-pycor) or (y < min-pycor)
      [ set hidden? true
        setxy x max-pycor]
      [set hidden? false
      setxy x y      ]                         

to oscillate
  ; this is for a driven system . . . either the top (blue) node
  ;   moves in a simple vertical oscillation,
  ;   or the top node moves in a circle
  ifelse (two-d-drive)
     [set x xzero + drive-amplitude * cos (ticks * drive-rate / ( 2 * pi))]
     [set x xzero]
  set y yzero + drive-amplitude * sin (ticks * drive-rate / ( 2 * pi))
  setxy x y

to fixed-top
  ; this is the Runge Kutta solver with the top node fixed
  ask turtles with [who != 0] [find-acceleration ]
  ask turtles with [who != 0][find-k1]
  ask turtles with [who != 0][find-acceleration ]
  ask turtles with [who != 0][find-k2]
  ask turtles with [who != 0][find-acceleration ]
  ask turtles with [who != 0][find-k3]
  ask turtles with [who != 0][find-acceleration ]
  ask turtles with [who != 0][update-coordinates]

to driven
  ; this is the Runge Kutta solver with driven top node
  ask turtle 0 [ oscillate ]
  ask turtles with [who != 0] [find-acceleration ]
  ask turtles with [who != 0][find-k1]
  ask turtles with [who != 0][find-acceleration ]
  ask turtles with [who != 0][find-k2]
  ask turtles with [who != 0][find-acceleration ]
  ask turtles with [who != 0][find-k3]
  ask turtles with [who != 0][find-acceleration ]
  ask turtles with [who != 0][update-coordinates]

to drop-slinky
  ; this is the Runge Kutta solver with all nodes
  ;    free to move
  ask turtles [find-acceleration ]
  ask turtles [find-k1]
  ask turtles [find-acceleration ]
  ask turtles [find-k2]
  ask turtles [find-acceleration ]
  ask turtles [find-k3]
  ask turtles [find-acceleration ]
  ask turtles [update-coordinates]

; The following three procedures are steps in the Runge Kutta process.
;   note that our differential equation shows up in each of these . . .
to find-k1
      set xtemp x
      set ytemp y
      set vxtemp vx
      set vytemp vy
      set kx1 vx
      set ky1 vy
      set jx1 (ax - b * vx )
      set jy1 (ay - b * vy - g) 
      set vx vxtemp + jx1 * (dt / 2)
      set vy vytemp + jy1 * (dt / 2)
      set x  xtemp +  kx1 * (dt / 2)
      set y  ytemp +  ky1 * (dt / 2)
      set ax 0
      set ay 0                                

to find-k2
      set kx2 vx
      set ky2 vy
      set jx2 (ax - b * vx )
      set jy2 (ay - b * vy - g) 
      set vx vxtemp + jx2 * (dt / 2)
      set vy vytemp + jy2 * (dt / 2)
      set x  xtemp +  kx2 * (dt / 2)
      set y  ytemp +  ky2 * (dt / 2)
      set ax 0
      set ay 0                                

to find-k3
      set kx3 vx
      set ky3 vy
      set jx3 (ax - b * vx )
      set jy3 (ay - b * vy - g) 
      set vx vxtemp + jx3 * dt 
      set vy vytemp + jy3 * dt 
      set x  xtemp +  kx3 * dt 
      set y  ytemp +  ky3 * dt 
      set ax 0
      set ay 0                                

; Using Newton's second law F=ma, find the acceleration of each node
;   based on the interaction with link neighbors. 
;   The mass is set to 1.
; Note that when spring-length = 0, this is a simple spring with force linearly
;   dependent on length.
;   With positive spring-length, the spring pulls (or pushes) toward
;      a rest length of spring-length . . .
to find-acceleration
    ask my-links [
      let fx 0
      let fy 0
      ;let f (-1) * k * (link-length)
      let f k * (spring-length - link-length)
      let myheading link-heading
      ifelse (myself = [end2] of self)
         [set fx f * sin myheading
          set fy f * cos myheading
         [set fx (-1) * f * sin myheading
          set fy (-1) * f * cos myheading
      ask myself [set ax (ax + fx)]
      ask myself [set ay (ay + fy)]

to setup-plot

;; plot y locations
to do-plots
  set-current-plot-pen "top"
  let ytop 0
  ask turtle 0 [ set ytop y ]
  plot ytop
  set-current-plot-pen "bottom"
  ask turtle (number-of-nodes - 1) [ set ytop y ]
  plot ytop
  set-current-plot-pen "c-of-mass"
  plot (sum [y] of turtles) / number-of-nodes

to check-movie  ; if filename is non-empty, make another snapshot
  if length filename > 0 [
    if (1 = (ticks mod 10))
       [ export-view word word word filename (round log ticks 10) ticks ".png" ]

;;;; Edge & Node utilities
to connect-edge [other-node] ; node proc: attach an edge between self and other
  ask other-node [ create-link-with myself
      set color gray

;;;; Utilities

to-report closest-xy [myx myy agent-set]  ; Return closest agent to x, y
  report min-one-of agent-set [distancexy-nowrap myx myy]