Posted: 27th Sep 2003 1:03
You may have seen other versions of this, it's not an original idea, I copied a Javascript version, although just the idea, the code is all mine.

Basically it is a string of elastic with beads attached. You can bounce it around the screen. Try changing the constants, in small steps though.

+ Code Snippet
`Elastic Physics Demo
`By Hamish McHaggis
`26/9/03
`This code demonstrates how to simulate the properties of elastic.  I saw it first on a javascript mouse
`trail, I have recreated it without looking at any of the javascript code.

`The amount of gravity acting on the beads
#CONSTANT GRAVITY 0.04
`The decay of the X movement of the beads, 1=no decay, 0=complete decay
#CONSTANT XDECAY 0.97
`The decay of the Y movement of the beads, 1=no decay, 0=complete decay
#CONSTANT YDECAY 0.97
`The number of beads on the string take into account that each bead weighs the beads above it down
#CONSTANT NUMBEADS 10
`The elasticity of the X movement of the beads
#CONSTANT XELASTICITY 0.02
`The elasticity of the Y movement of the beads
#CONSTANT YELASTICITY 0.02
`The amount the bead movement decays when it hits a wall, 1=no decay, 0=complete decay
#CONSTANT WALLDECAY 0.9
`The between beads, before the string tenses and elasticity acts
#CONSTANT SLACKNESS 1
`The diameter of the beads
#CONSTANT BEADSIZE 6

`Screen mode
screenWidth as word = 800
screenHeight as word = 600
set display mode screenWidth,screenHeight,16

beadDist as float
beadDistX as float
beadDistY as float
distRatioX as float
distRatioY as float

sync on
sync rate 60

type beadType
   X as float
   Y as float
   xMove as float
   yMove as float
endtype

dim bead(NUMBEADS) as beadType

position mouse 0,0

do
   `Draw background
   ink rgb(255,255,255),0
   box 0,0,screenWidth,screenHeight

   `Position parent bead
   bead(1).X=mousex()
   bead(1).Y=mousey()
   if bead(1).X-(BEADSIZE+10)/2<0 then bead(1).X=(BEADSIZE+10)/2
   if bead(1).X+(BEADSIZE+10)/2>screenWidth then bead(1).X=screenWidth-(BEADSIZE+10)/2
   if bead(1).Y-(BEADSIZE+10)/2<0 then bead(1).Y=(BEADSIZE+10)/2
   if bead(1).Y+(BEADSIZE+10)/2>screenHeight then bead(1).Y=screenHeight-(BEADSIZE+10)/2

   `Draw parent bead
   ink rgb(0,0,0),0
   circle bead(1).X,bead(1).Y,BEADSIZE

   `Loop though other beads
   for x=2 to NUMBEADS
      `Work out X and Y distance between the bead and the one before it
      beadDistX=bead(x).X-bead(x-1).X
      beadDistY=bead(x).Y-bead(x-1).Y
      `Work out total distance
      beadDist=sqrt(beadDistX^2+beadDistY^2)

      `If the beads are far enough apart, decrease the movement to create elasticity
      if beadDist>SLACKNESS
         dec bead(x).xMove,XELASTICITY*beadDistX
         dec bead(x).yMove,YELASTICITY*beadDistY
      endif

      `If bead is not last bead
      if x<>NUMBEADS
         `Work out distances between the bead and the one after it
         beadDistX=bead(x).X-bead(x+1).X
         beadDistY=bead(x).Y-bead(x+1).Y
         beadDist=sqrt(beadDistX^2+beadDistY^2)

         `If the beads are far enough apart, decrease the movement to create elasticity
         if beadDist>1
            dec bead(x).xMove,XELASTICITY*beadDistX
            dec bead(x).yMove,YELASTICITY*beadDistY
         endif
      endif

      `Decay the movement of the beads to simulate loss of energy
      bead(x).xMove=bead(x).xMove*XDECAY
      bead(x).yMove=bead(x).yMove*YDECAY

      `Apply gravity to bead movement
      inc bead(x).yMove,GRAVITY

      `Move beads
      inc bead(x).X,bead(x).xMove
      inc bead(x).Y,bead(x).yMove

      `If the beads hit a wall, make them bounce off of it
      if bead(x).X-(BEADSIZE+10)/2<0
         bead(x).X=+(BEADSIZE+10)/2
         bead(x).xMove=-bead(x).xMove*WALLDECAY
      endif
      if bead(x).X+(BEADSIZE+10)/2>screenWidth
         bead(x).X=screenWidth-(BEADSIZE+10)/2
         bead(x).xMove=-bead(x).xMove*WALLDECAY
      endif
      if bead(x).Y-(BEADSIZE+10)/2<0
         bead(x).yMove=-bead(x).yMove*WALLDECAY
         bead(x).Y=(BEADSIZE+10)/2
      endif
      if bead(x).Y+(BEADSIZE+10)/2>screenHeight
         bead(x).yMove=-bead(x).yMove*WALLDECAY
         bead(x).Y=screenHeight-(BEADSIZE+10)/2
      endif

      `Draw bead and string from it to the one before it
      ink rgb(0,0,0),0
      circle bead(x).X,bead(x).Y,BEADSIZE
      ink rgb(200,100,0),0
      line bead(x).X,bead(x).Y,bead(x-1).X,bead(x-1).Y
   next x

   text 20,20,str$(screen fps())
   sync
   cls
loop


Version 2
+ Code Snippet
`Elastic Physics Demo 2.0
`By Hamish McHaggis
`26/9/03

`This code demonstrates how to simulate the properties of elastic.  I saw it first on a javascript mouse
`trail, I have recreated it without looking at any of the javascript code.

`The amount of gravity acting on the beads
#CONSTANT GRAVITY 0.04
`The decay of the X movement of the beads, 1=no decay, 0=complete decay
#CONSTANT XDECAY 0.97
`The decay of the Y movement of the beads, 1=no decay, 0=complete decay
#CONSTANT YDECAY 0.97
`The number of beads on the string take into account that each bead weighs the beads above it down
#CONSTANT NUMBEADS 10
`The elasticity of the X movement of the beads
#CONSTANT XELASTICITY 0.02
`The elasticity of the Y movement of the beads
#CONSTANT YELASTICITY 0.02
`The amount the bead movement decays when it hits a wall, 1=no decay, 0=complete decay
#CONSTANT WALLDECAY 0.9
`The between beads, before the string tenses and elasticity acts
#CONSTANT SLACKNESS 1
`The diameter of the beads
#CONSTANT BEADSIZE 6

`Screen mode
screenWidth as word = 800
screenHeight as word = 600
set display mode screenWidth,screenHeight,16

beadDist as float
beadDistX as float
beadDistY as float
distRatioX as float
distRatioY as float
oX as float
oY as float
grabbedBead as integer

sync on
sync rate 60

type beadType
   X as float
   Y as float
   xMove as float
   yMove as float
   fixed as boolean
endtype

dim bead(NUMBEADS) as beadType

position mouse 0,0

do
   `Draw background
   ink rgb(255,255,255),0
   box 0,0,screenWidth,screenHeight

   `If no bead is grabbed
   if grabbedBead=0
      `If mouse is clicked
      if mouseclick()>0
         `If LMB is clicked then detect whether to pick a bead
         if mouseclick()=1
            for x=1 to NUMBEADS
               if sqrt((mousex()-bead(x).X)^2+(mousey()-bead(x).Y)^2)<=BEADSIZE
                  grabbedBead=x
                  position mouse bead(grabbedBead).X,bead(grabbedBead).Y
                  exit
               endif
            next x
         else
            `If RMB is clicked, pick bead 1
            grabbedBead=1
            position mouse bead(grabbedBead).X,bead(grabbedBead).Y
         endif
      endif
   else
      `If bead is grabbed...
      `Store old bead position
      oX=bead(grabbedBead).X
      oY=bead(grabbedBead).Y
      `Get new bead position
      bead(grabbedBead).X=mousex()
      bead(grabbedBead).Y=mousey()
      `Bead movement=0
      bead(grabbedBead).xMove=0
      bead(grabbedBead).yMove=0
      `If f is pressed fix/release the bead
      if lower$(inkey$())="f"
         if fHold=0
            bead(grabbedBead).fixed=1-bead(grabbedBead).fixed
            grabbedBead=0
            fHold=1
         endif
      else
         fHold=0
      endif
      `If mouse is released
      if mouseclick()=0
         `If object isn't fixed then give it momentum, so you can 'throw' the beads
         if bead(grabbedBead).fixed=0
            bead(grabbedBead).xMove=bead(grabbedBead).X-oX
            bead(grabbedBead).yMove=bead(grabbedBead).Y-oY
         endif
         grabbedBead=0
      endif
   endif

   `Loop though other beads
   for x=1 to NUMBEADS
      `If r is pressed release bead
      if lower$(inkey$())="r" then bead(x).fixed=0
      `If bead isn't fixed
      if bead(x).fixed=0
         if x<>1
            `Work out X and Y distance between the bead and the one before it
            beadDistX=bead(x).X-bead(x-1).X
            beadDistY=bead(x).Y-bead(x-1).Y
            `Work out total distance
            beadDist=sqrt(beadDistX^2+beadDistY^2)

            `If the beads are far enough apart, decrease the movement to create elasticity
            if beadDist>SLACKNESS
               dec bead(x).xMove,XELASTICITY*beadDistX
               dec bead(x).yMove,YELASTICITY*beadDistY
            endif
         endif

         `If bead is not last bead
         if x<>NUMBEADS
            `Work out distances between the bead and the one after it
            beadDistX=bead(x).X-bead(x+1).X
            beadDistY=bead(x).Y-bead(x+1).Y
            beadDist=sqrt(beadDistX^2+beadDistY^2)

            `If the beads are far enough apart, decrease the movement to create elasticity
            if beadDist>1
               dec bead(x).xMove,XELASTICITY*beadDistX
               dec bead(x).yMove,YELASTICITY*beadDistY
            endif
         endif

         `Decay the movement of the beads to simulate loss of energy
         bead(x).xMove=bead(x).xMove*XDECAY
         bead(x).yMove=bead(x).yMove*YDECAY

         `Apply gravity to bead movement
         inc bead(x).yMove,GRAVITY

         `Move beads
         inc bead(x).X,bead(x).xMove
         inc bead(x).Y,bead(x).yMove

         `If the beads hit a wall, make them bounce off of it
         if bead(x).X-(BEADSIZE+10)/2<0
            bead(x).X=+(BEADSIZE+10)/2
            bead(x).xMove=-bead(x).xMove*WALLDECAY
         endif
         if bead(x).X+(BEADSIZE+10)/2>screenWidth
            bead(x).X=screenWidth-(BEADSIZE+10)/2
            bead(x).xMove=-bead(x).xMove*WALLDECAY
         endif
         if bead(x).Y-(BEADSIZE+10)/2<0
            bead(x).yMove=-bead(x).yMove*WALLDECAY
            bead(x).Y=(BEADSIZE+10)/2
         endif
         if bead(x).Y+(BEADSIZE+10)/2>screenHeight
            bead(x).yMove=-bead(x).yMove*WALLDECAY
            bead(x).Y=screenHeight-(BEADSIZE+10)/2
         endif
         ink rgb(0,0,0),0
      else
         ink rgb(255,0,0),0
      endif

      `Draw bead and string from it to the one before it
      circle bead(x).X,bead(x).Y,BEADSIZE
      ink rgb(200,100,0),0
      if x<>1 then line bead(x).X,bead(x).Y,bead(x-1).X,bead(x-1).Y
   next x

   ink rgb(200,200,200),0
   text 10,10,"FPS: "+str$(screen fps())
   text 10,30,"Left Click to Grab a Bead"
   text 10,45,"Right Click to Grab the First Bead"
   text 10,60,"'F' to fix/release a bead in the air, while you are grabbing it"
   text 10,75,"'R' to release all beads"
   sync
   cls
loop
Posted: 27th Sep 2003 1:08
Very nice demonstration of maths you have there.
Posted: 27th Sep 2003 4:10
New better version, where you can fix the beads in place above.
Posted: 27th Sep 2003 11:44
thats very cool!
Posted: 27th Sep 2003 18:09
I liked playing around with that. Maybe you should make it so one of the beads moves to a random area on the screen, and make it a screen saver. That'd be neat.
Posted: 27th Sep 2003 21:00
Here is a cool combination of settings. Just replace the current settings with these. You will need a fastish computer to process all the 100 beads at 60fps...

+ Code Snippet
`The amount of gravity acting on the beads
#CONSTANT GRAVITY 0.02
`The decay of the X movement of the beads, 1=no decay, 0=complete decay
#CONSTANT XDECAY 0.59
`The decay of the Y movement of the beads, 1=no decay, 0=complete decay
#CONSTANT YDECAY 0.59
`The number of beads on the string take into account that each bead weighs the beads above it down
#CONSTANT NUMBEADS 100
`The elasticity of the X movement of the beads
#CONSTANT XELASTICITY 0.7
`The elasticity of the Y movement of the beads
#CONSTANT YELASTICITY 0.7
`The amount the bead movement decays when it hits a wall, 1=no decay, 0=complete decay
#CONSTANT WALLDECAY 0.9
`The diameter of the beads
#CONSTANT BEADSIZE 6
Posted: 27th Sep 2003 23:35
Heh, I could run 500 beads at a decent speed (30 FPS)
Posted: 28th Sep 2003 13:21
Yeah, I said fairly , I still get over 20fps with 1000 beads, although it's kind of pointless.
Posted: 28th Sep 2003 16:54
I only got about 14 with 1000, funny watching them squirm around on the bottom of the screen
Posted: 29th Sep 2003 22:00
That is a really good physique demonstration!
Looks really realistic.
Posted: 20th Oct 2003 20:26
Great demo...Thanks...
Posted: 24th Oct 2003 7:49
woh, thats neat!
Posted: 24th Oct 2003 13:42
nice... you know if you combined this with a box collision and added it to mesh you could have a nice ragdoll physics system on your hands
Posted: 28th Oct 2003 15:43
Yeah, I could try that Raven, just need to get a bit more used to memblocks in dbpro.