The Physics of an Elastic: Part 1
May 24, 2000
by Danny Kodicek
Introduction
Take a weight and tie it to the end of a stretched out rubber band. Bounce it up and down a few times. How does that look? How would it look if you were on the moon? How would it look if you tied two rubber bands together? How about if you used a piece of string instead of an elastic? What if the weight was heavier? In these two articles, I'll look at the means by which you can simulate all of these things.
This is essentially a practical guide to creating elastic effects in Director, but I shall be explaining the physical principles behind the code. Inevitably, this means that there will be some physical formulae, and on occasion some mathematical manipulation of these formulae. If you are not comfortable with this part of the discussion, in many cases you can just bleep them out as you read, and just skip to the code examples, but I hope they are not too hard to follow.
The basic physics
To understand how an elastic (or a spring) works, there is only one formula you need to know. It is Hooke's Law, and the most common way to state it is like this:
Force due to elastic = c * Extension of elastic
where c is a positive constant for the elastic, called the coefficient of elasticity. The extension is the stretched length of the elastic minus its unstretched length, and the force is directed inwards along the elastic.
To make this more concrete, suppose there is an elastic band which is normally twenty units long, and you stretch it between your two hands to thirty units, each hand experiences a force inwards of c*10 (obviously, the value of c depends on the units you are using - when simulating these things on a computer, I usually have a standard unit of one pixel)
With a little fiddling around, it is also possible to derive a second formula - which is really just a restatement of the same law, but it will be useful later.
The energy stored in a stretched spring = c * extension * extension / 2
We will come back to this in the next article.
We are considering here, incidentally, idealised elastics, which is to say, they are light (massless), infinitely extensible, and cannot be tangled. At the end of the next article, I'll briefly talk about adding physical constraints on the system. For the moment, it's just worth noting that Hooke's law only applies up to a certain point - called the elastic limit of the elastic - which depends on the material. After that point, the law still applies, but the coefficient of elasticity c becomes greater. Further still beyond the limit, the elastic will break as the material stresses become too great.
One more piece of terminology which is worth mentioning is the word particle. All this means is the thing on the end of the elastic, in order to avoid confusion with other words like mass or weight. It also implies certain physical constraints: a particle is presumed to be a point mass - one which has negligible volume. In most cases, as long as the elastic is attached to the centre of gravity of the object, this is an acceptable assumption.
Simple Harmonic Motion
The most common motion for a mass on the end of a spring is called Simple Harmonic Motion. In fact, SHM occurs in many situations in nature, including a pendulum (actually, SHM is a slight approximation for a pendulum, but it's close enough), a cork bobbing in a water wave, the vibration of a plucked string and so on.
Director 7 download for Mac or PC.
You can think of SHM in two ways when dealing with a stretched spring. I prefer to think of it as a spring hanging vertically, with the particle bobbing due to gravity, as above. Alternatively, if you are using a spring that has a compressive force as well as an extensive force, you can think of it as a particle bobbing horizontally.
The formula for Simple Harmonic Motion is this:
Distance from equilibrium at time t = A * sin(k * t)+B * cos(k * t)
Here, k is another constant, which is given by k=sqrt(c/mass). A and B are also constants, but unlike k, they depend on the particular oscillation, rather than the spring.
With a little calculus, you can derive a second result:
Velocity of particle at time t = k * (A * cos(k * t) - B * sin(k * t))
Both Distance and Velocity should be measured in the same direction
The easiest way to calculate the constants A and B is to see that k*A is the spring's initial speed (measured downwards), and B is its initial extension (as you will see if you substitute the value t=0 in the two equations). You might think that the gravitational force might also play a part, but in fact all it changes is the equilibrium position, as we will see later.
Have a try with the movie above. Drag the particle downwards and let go - you will see that it oscillates, and never goes lower than the point at which you let go of it. Now try 'throwing' it, to give it a starting speed. Try playing with the sliders that control the mass and elasticity, too. (Ignore the Damping slider for now). You need to press the Apply Settings button for the new settings to take effect.
Applying this in a behaviour is pretty straightforward: you can just plug it in. Here is a simple example. The property pconstant is the value k mentioned earlier, which depends on the mass and elasticity. Prefloc is the equilibrium position. Pstarttime is measured by the milliseconds
on exitframe me
t = (the milliseconds-pstarttime)/1000.0
x = pconstant * t
y = pstartloc * cos(x) + pstartspeed * sin(x)/pconstant
l = prefloc+y
sprite(me.spritenum).locv = l
end
If you check the sample movie, you'll find that the code is a little more complicated, for two reasons. Firstly, it takes into account damping, which I will explain in a moment. Secondly, it has to allow clicking, dragging and throwing the particle, as well as receiving messages from the sliders. I'll look at the full code in more detail below.
Why does the SHM formula work? Well, if you want to get technical, it's because it's the general solution of the differential equation:
acceleration ~ -c * extension
In the next article we'll see a little of the physical backing behind it. You may also be wondering why this behaviour is so common. Well, it's a very natural motion for anything which has an equilibrium state that it's trying to maintain, as can be seen by the differential equation. Anywhere that you have a force that is directed back towards equilibrium, you are likely to find something like SHM.
Another way to visualise SHM is to imagine a piece of chewing gum on the rim of a wheel. If you look at the wheel end on and watch the vertical position of the gum as the wheel spins, it performs SHM.
Damped Harmonic Motion
In the example movie above, unless you change the settings the weight will bob up and down indefinitely, never changing its motion. In the real world, this doesn't happen, and in fact the weight gradually comes to rest. This phenomenon is called Damping. Try playing with the Damping slider in the above movie
The formula for DHM is very similar to SHM, but it adds a new term:
Extension at time t = (A * sin(k * t) + B * cos(k * t)) * exp(-d * t)
d is a new positive constant, the damping factor, which depends on the spring, the fluid through which the particle is moving (air, water, glycerine), etc. If d is very large, the exponential function will quickly become zero. If it's small, it will take a long time, and if it's zero, it will make no difference (since exp(0)=1).
So, with damping added, we can now create a full behaviour for SHM. The whole thing is in the movie, but here is the main meat:
on exitframe me
t = (the milliseconds-pstarttime)/1000.0
if pdrag then
-- dragging - check velocity
l = the mousev-poffset
pstartspeed = (l - sprite(me.spritenum).locv)/t
sprite(me.spritenum).locv = l
pstarttime = the milliseconds
sendallsprites(#updateparticle,l)
else
-- autonomous - check elastic
x = pconstant * t
y = (pstartloc * cos(x) + pstartspeed * sin(x)/pconstant) * exp(-pdamp * t)
sprite(me.spritenum).locv = prefloc + y
sendallsprites(#updateparticle,prefloc+y)
end if
end
As you can see, the first half of this handler deals with the situation where you are dragging the particle. In that case, all it does is at each iteration to check what the current dragging speed is, by seeing how far the particle has moved since the last time. When you let go, this value will become the new initial speed.
In the second half, the particle is moving under DHM. The values are simply plugged into the formula (as before, recall that A=initial velocity / k) and the resulting distance from equilibrium is added to the constant prefloc, which is the equilibrium position read in on beginsprite. (The 'updateparticle' call is simply to allow the line representing the spring to update itself. Depending on the complexity of your movie, you might need to make this more specific as to which particle is updating)
Unfortunately, adding the damping factor makes the calculation of Velocity a little more complicated. Again, by using a little calculus, the formula turns out to be:
Velocity(t)=( (k * A - d * B) * cos (k * t) - (k * B+d * A) * sin (k * t) ) * exp (-d * t)
This is pretty scary-looking - but don't worry too much about it. If you just plug the numbers in, it works without any trouble. I use this formula in the behaviour in order to calculate the current speed when applying new settings:
on applysettings me
-- calculate the current speed and position
t = (the milliseconds - pstarttime)/1000.0
x = pconstant * t
-- see the article for an explanation of this monster:
currspeed=((pdamp * pstartspeed/pconstant - pconstant * pstartloc) * sin(x) + (pdamp * pstartloc + pstartspeed) * cos(x)) * exp(-pdamp * t)
pstartloc = (pstartloc * cos(x) + pstartspeed * sin(x)) * exp(-pdamp * t)
pstartspeed = currspeed
-- these values become the new initial value, and we restart.
pstarttime = the milliseconds
end
This is probably the most complicated part of the behaviour, so it's worth going through in more detail. Essentially, what we are doing is to apply the new settings to a particle that is still moving under the previous settings. In order to do this, we have to work out the speed and position of the particle. We do this by plugging the value of t into the two formulae. At that point, we start a new DHM motion, with the current start time, and the values we have calculated as the initial speed and position. The result is a seamless change between the two motions.
Gravity
As I said before, gravity plays very little part in the equation of motion of the particle. However, it does affect the equilibrium position. In the movie above, changing the mass of the particle will not make it move, whereas as we know from real life, if you put a particle onto the pan of a set of scales, the pan moves down and the scales can measure the weight accordingly.
The equilibrium position of the particle is the point at which the upward force is balanced by the downward force due to gravity. We can calculate this quite easily from Hooke's law:
Force due to gravity = mass * g
(where g is the acceleration due to gravity - on this planet, 9.8 m/sec/sec). So at the equilibrium position:
mass * g = c * extension
so
equilibrium extension = mass * g / c
We can use this to simulate a spring scales, as shown below. Drag the weights to the scales to work out their heights in pixels. Note the SHM clock in the background.
Taking it further
So far, we've seen how to deal with fixed springs and elastics, which are anchored to a particular point, and we've seen how the motion of these elastics can be calculated by a precise formula, Damped Harmonic Motion. And for as long as we want precise formulae, that's as far as we can go. But if we are willing to make an approximation, we can create far more complex motion. In the next article, I'll look at a much more generalised elastic, and we'll see how far we can take it.
Copyright 1997-2024, Director Online. Article content copyright by respective authors.