Articles Archive
Articles Search
Director Wiki

The Physics of an Elastic: Part 2

May 30, 2000
by Danny Kodicek


Last time, I explained how to create some realistic spring and elastic effects by using the formulae for Simple Harmonic Motion and Damped Harmonic Motion, culminating in two simple movies. This time, I promised that I would explain how to create more complex behavior by approximation methods. I'm going to look at the general motion of a particle on an elastic, and I'll also briefly look at two important side effects of the physics, resonance and coupling.

I'm going to start by briefly reminding you of the most important physical principle involved: Hooke's Law, which states that…

Force due to elastic = - c * extension of elastic

… where c is the coefficient of elasticity of the elastic (or spring) and the extension is the stretched length of the spring minus its unstretched length. The other important formula, which is a restatement of the same law, is…

Energy stored in a stretched spring = 0.5 * c * extension * extension

We shall be using both versions of the law a great deal in this article.

The general motion of a particle

Okay, before we go any further, here is the motion we are going to create. In the movie below, the small blue particle is supposed to be swinging freely on the end of an elastic, while the large black one is fixed. You can drag either of them around, and you can also throw the small particle to give it a velocity. Use the sliders and click on 'apply settings' to change the various parameters; you'll notice that the velocity of the particle is set to zero at that instant. This is to avoid weird behavior, as I'll explain in a moment.

Director 7 sample movies are available for download in Mac or PC format.

So how does it work?

There are two forces on a mass attached to an elastic band (actually, three, counting damping, but I'm afraid I'm going to ignore damping in this case -- it complicates things way too much. I'll talk briefly about how it might be applied later). The first is gravity. That's proportional to the mass, and acts the same at all times (unless you go really high up).

Force due to gravity = mass * acceleration due to gravity

Then there's the elastic force, which was given by Hooke's law, above.

At any moment, it's possible to calculate both these forces. Measure the distance between the mass and the fulcrum, and take off the unstretched length. That gives you the extension, and so the elastic force. If we're clever, we can also say it's a force in a particular direction, namely towards the fulcrum. We can use Director's inbuilt point calculations to keep track of this vector.

We can then add the constant gravitational force, and since we're using vectors, we add it as point(0,mass*gravity) (measuring down as positive).

So, here is the beginning of our Lingo behavior:

-- vector of elastic
e = sprite(me.spritenum).loc-sprite(psprite).loc

-- length of elastic
d = vectorlength(me,e)

-- gravitational force on particle
f = point(0,pmass*pgravity)
if d > plength then
  -- elastic force if the elastic is extended
  f = f - e * (d - plength) * pelasticity/d
end if

Three points to note:

  1. The function 'vectorlength' is given by Pythagoras' Theorem: the length of a vector -- that is, a line or a Director point value point(x,y) -- is given by sqrt(x^2 + y^2). We can use the same function to work out the distance between two points as above: e is the vector joining the two points given by the loc of the particle and the anchor, so vectorlength(e) is the distance between the points.
  2. The force due to gravity is measured downwards. We show this by creating the vector f, which is given by point(0, gravitational force).
  3. The force due to the elastic is measured in the direction of the elastic. This is achieved by multiplying the vector e, which is already in the right direction, by the elastic force, and dividing by its original length. By adding this to the vector force due to gravity we get the total vector force on the particle.

These vector calculations may seem a little weird if you aren't used to them. In fact, they are a very powerful tool and Director's ability to make vector calculations is a great help in any physical simulation.

So, now that we have calculated the force on the particle, we can use Newton's laws (which you may remember from school) to calculate the acceleration of the particle. As long as it has been a short time period (say, one frame) since the last time we checked, this linear motion will be close to the real thing. Newton's laws give us:

acceleration = total force / mass

And new position = current velocity * time + acceleration * time * time / 2

In Lingo:

-- acceleration
a = f/pmass

-- new relative position
s = pvelocity * pspeed * t + .5 * a * power(t,2)

-- new absolute position
pos=sprite(me.spritenum).loc + s

As before, all these are vectors, and so they allow us to calculate both the horizontal and vertical components of the motion simultaneously.

But now there is a problem. This is an approximation, and if we calculate both the new velocity and the new position by this method, we find that the oscillation gets steadily greater as errors accumulate. This is not acceptable. So the solution is to calculate the velocity from the energy of the particle, which we know must be the same at all times (at least, until we change the parameters or apply a force). Strictly speaking, it is the total energy of the system that must be constant, but because the fulcrum is not moving (unless we drag it), its own energy doesn't change, so we can ignore it.

The energy of the particle is given by

E = elastic energy + kinetic energy + gravitational energy

where elastic energy is as given before,

kinetic energy = mass * speed * speed / 2

gravitational energy = mass * acceleration due to gravity * height

(height is measured from an arbitrary reference point. I've taken the top of the screen, so I can use the locv - or rather, measured upwards, -(the locv))

After we have calculated the new position, we can work out the new elastic energy. and we can also work out the new gravitational energy. So, if we subtract these from the total energy, which is a constant, we know the new kinetic energy, and hence the speed of the particle. We also know the direction of travel, which is along the vector of movement. So from these two, we have the new velocity.

-- new extension
newd = me.vectorlength(pos-sprite(psprite).loc)

if newd > plength then
  newpotential= .5 * pelasticity * power((newd - plength),2)
  newpotential = 0
end if

kineticenergy = penergy - newpotential + pmass * pgravity * pos[2]

if kineticenergy <= 0 then
  pspeed = 0
  pspeed = sqrt(2 * kineticenergy/pmass)
  pvelocity = me.norm(s)
end if

Note that I have allowed for the situation where kinetic energy (which is a scalar quantity rather than a vector) is less than zero. This is a contingency, which shouldn't happen in reality but does occasionally owing to the approximations we are making.

One more thing to notice at this stage is that I have split the velocity of the particle into two values for ease of calculation: pspeed, which is a scalar; and pvelocity, which is a normalized vector (that is, a vector of length 1). I use the function norm(s), which returns s/vectorlength(s), to normalize the vector. Because pvelocity will always be measured in the current direction of travel, we use the vector s, the relative position of the particle, to measure it.

Check the behavior in the sample movie to see these calculations in full. But the main sequence, summed up, is as follows:

We know the current energy, the current speed, the current position of the mass and the fulcrum, and the time since the last measurement.

Total force = force due to gravity + force due to elastic

From which we can work out the new position, and direction of travel. Then we calculate the new kinetic energy by:

Kinetic energy = current energy - gravitational energy - elastic energy

So the new speed is

sqrt (kinetic energy* 2 / mass)

So the only factor left is to work out the current energy. We can do this at the beginning of each frame, before calculating the motion, but since energy is constant unless a force is applied, we can save some time by only calculating it if there is a change. So we should calculate the energy:

In each case, the energy is calculated directly using the formula below:

on setenergy me
  e = sprite(me.spritenum).loc - sprite(psprite).loc
  d = me.vectorlength(e) -- length of elastic
  if d > plength then
    energy=.5 * pelasticity * power((d - plength),2)
    energy = 0
  end if
  penergy = energy + .5 * pmass * pspeed * pspeed - pmass * pgravity * sprite(me.spritenum).locv

The only important point here is that in the above calculation we are subtracting, rather than adding, the gravitational potential energy. This is because, as mentioned before, I have taken my zero position to be at the top of the screen, since the locv is measured downwards.

And that's it! In the full behavior, there are additional factors to do with communication with other sprites, and managing the click / drag / throw functionality, but the physical behavior is all here.

Finally, what about damping? Well, there is a problem with adding damping by this method: damping violates the law of conservation of energy, since it is a force against the motion. We could simulate it by adding a constant decrease in the kinetic energy of the system (strictly, an exponential decrease), but this is quite tricky; and let's face it, this is complicated enough. But if you're interested, you might want to have a go.

Resonance and Coupling

Springs and elastics have a number of wonderful properties that are all just a result of that simple law given right at the start. I'm going to look at two of them briefly, without any Lingo or equations.

The first phenomenon is called resonance, where a small oscillation of the right frequency on one end of a spring can drive an ever-increasing oscillation of the other. This sounds complicated, but it's quite simple; the easiest example is pushing a child on a swing, where a small amount of force applied periodically can drive the oscillation higher and higher.

In this movie, the fulcrum sprite is oscillating with a set frequency. You can change the form of the oscillation with the radio buttons, as well as the period (time for one complete oscillation) and amplitude (height of the oscillation). Incidentally, in this movie, unlike previous ones, the sliders work continuously -- hence the fact that there is no 'Apply settings' button. Just drag them to change the motion.

As you will see, when you change the frequency, it can drive the particle bouncing freely to higher and higher values. This is independent of the precise form of the driving oscillation. At precisely the right period (in fact, it is the natural period of the spring, given by 2*pi /k as mentioned in the previous article), the oscillation starts to increase rapidly, even with a very small amplitude of the driving oscillation. (Actually, this depends to some extent on whether the oscillation is 'in phase' or 'out of phase' with the current oscillation of the particle. If it's out of phase, the driving oscillation will actually slow the particle down. But once the particle has been slowed to nothing, it starts to increase again, so in the long run, the motion is the same.) The same effect will occur at periods that are whole number multiples of this base period, although the motion of the particle becomes more erratic.

In the previous movie, the behavior on the particle is exactly as it was before. In the final movie, I have set things up rather differently. This movie displays the result of coupling, which is to say, what happens when you link two or more elastics together. This time, I have two behaviors, one on the elastics themselves, which holds four pieces of information: the elasticity and unstretched length, and the two sprites to which the elastic is attached. On each exitframe, it calculates the elastic force and sends this as a message to the two sprites. The sprites, which know only their own mass and the acceleration due to gravity (in this movie, a global variable), sum up all the forces that they have received, and move accordingly.

In this case the method above, using the energy of the system, is not so easy to apply. This is because the law of conservation of energy applies only to the whole system of all the particles, and becomes extremely difficult to calculate. Therefore, I have used Newton's laws to calculate both the position and the velocity of the particles. This means that, as I mentioned, the energy of the system tends to increase gradually. I have added a kind of 'damping factor' to the velocity to cut this effect down, but it is very much a trial-and-error solution. However, it is realistic enough for you to see the kind of physical behavior you can get.

The particles can either be fixed in place (green particles) or moving freely (blue particles), and either draggable or not (all of the sprites in the sample movie are set to be draggable). If you double-click a particle, it will toggle between being fixed and free. Play around and see what kind of effects you can create -- not just with the five-particle system in the Shockwave, but in general with the whole movie.

Taking it further

This is really all I have space for, but you might want to think about some more modifications you could make to explore these ideas even further. It might be interesting to start adding physical constraints on the system. How about a bouncing floor? Or a spring that has a maximum and minimum length or elastic limits, or a rigid rod? Once you understand the physics of the system, it's not hard to add any of these. Combine these ideas with Raman Pfaff's explanation of collisions, and you have almost a complete picture of the Newtonian world (just add gravity and friction, and simmer).

Well, it's been hard work, but I hope it was worth it. It's amazing how much you can get out of that one simple law. If you want more, it's worth searching the web. There's quite a lot of stuff out there that's well presented, especially on straightforward SHM and DHM. How you apply it to what you're doing is up to you -- a bungee-jumping game, anyone?

Danny is a mathematician by training, an occasional writer, actor and, for the last four years, programmer. He is self-taught in Director and it occasionally shows. He is part of the company Wellspring Interactive Ltd and has just finished working as Head of Clues on their first major project, TimeHunt.

Copyright 1997-2019, Director Online. Article content copyright by respective authors.