Spring Physics

Introduction

Hi, I’m Glenn Fiedler and welcome to the fourth article in my series on Game Physics.

In the previous article we discussed how to simulate the motion of rigid bodies in 3D.

Now we’re going to discuss spring physics.

The physics behind springs is simple but extremely versatile and useful. You can use springs to link points together to model rope and string, cloth, and even blobs of jelly. Springs can also be used to implement basic collision response, and to create joints that constrain the motion of rigid bodies.

The more physics programming you do, the more springs pop up. Many physical phenomenon boil down to spring-like forces being applied such as buoyancy in water. Springs are everywhere so lets discover how to simulate them!

Spring and dampers

The formula to use for simulating spring-like behavior is called Hooke’s Law.

    F = -kx

Where x is the vector displacement of the end of the spring from it’s equilibrium position, and k is a constant describing the tightness of the spring. Larger values of k mean that the spring is tighter and will therefore stretch less per unit of force, smaller values mean the spring is looser and will stretch further.

Newton’s third law says that every force has an equal and opposite force. If two objects a and b are connected together by a spring then the spring will apply one force which pulls object a towards object b, and an equal and opposite force pulling object b towards a. However, if you want to attach one object to a fixed point in space its you can apply the force of the object in one direction. This makes sense is you consider that a point which cannot move as having infinite mass.

Spring forces alone are not much use though. You need to combine them with dampers to have a realistic simulation. Damping simulates energy loss, and it is used in physics simulations to make sure that springs don’t oscillate forever but come to rest over time.

A spring-damper system can be modeled as follows:

    F = - kx - bv

Where b is the coefficient of damping and v is the relative velocity between the two points connected by the spring. Larger values for b increase the amount of damping so the object will come to rest more quickly.

The importance of a good integrator

This brings me to a very important point. Perhaps I was overly harsh in my first article when it comes to the Euler integrator. There are situations where you don’t need the full accuracy of RK4. For example, if you are just simulating basic rigid body dynamics and collision response you can probably get away with just an Euler integrator. Euler integration is not inherently crap.

However, my harshness was inspired by a few things. Firstly, its really not that hard to implement an RK4 integrator. Secondly, in my experience, most physics simulation time is spent in collision detection and response, not in the integrator. Using an Euler integrator instead of RK4 is not going to add a significant computation overhead to your physics simulation unless you are doing a simulation of thousands of particles. The bottom line is that for most applications in game physics, there is little reason not to use RK4.

But the real reason I love using an RK4 integrator is this: its significantly increases the tightness of the springs that you can model. Given that a lot of physical phenomenon end up applying spring like forces, if you plan on doing any serious modeling of forces in your simulation, it really pays to use a high accuracy integrator like RK4. If you have ever used Euler integrators and springs in a physics simulation then you know how frustrating it feels when your simulation explodes.

Variations on springs

There are many different variations on spring-damper systems, but what I want to do is explain how to think generally in terms of what the forces are doing so that you can easily design spring and damper systems to achieve whatever effect you want.

The first thing is that springs don’t only have to act to pull two points together so that they lie on top of each other. For example you can design spring forces that pull together or push apart two points apart so they maintain a desired separation distance from each other:

    F = -k(|x|-d)(x/|x|) - bv

Where |x| is the distance between the two points connected to the spring, d is the desired distance of separation, and x / |x| is the unit length direction vector between the two points: a to b, when applying the force to point a and vice versa.

The overall effect of the force equation above is to have a force which pushes the two points connected by the spring apart if they are closer than distance d, and bring the two points together if they are further than d apart. Notice how the force becomes exactly zero when the two points are at the target distance? If you tune the k and b parameters correctly you can have a nicely behaving spring that quickly brings the two points together smoothly over time and comes to rest at the solution point.

But why apply springs to position only? If you want to accelerate a body over time such that it accelerates to a certain speed then you can calculate a spring force proportional to the difference between the current velocity and the target velocity, combined with a damping proportional to the current velocity so that it reaches its target over time instead of cycling about it. This is usually called a motor in physics simulation.

We can even apply the same concept to drive the spinning of an object at a certain speed by applying a spring torque proportional to the difference between the current angular velocity and the desired angular velocity, coupled with a damper force proportional to the current angular velocity.

Another commonly implemented spring constraint is to enforce a upright orientation of a body, for example, you could apply a spring torque proportional to the difference between the current orientation and an upright orientation, coupled with a damper proportional to angular velocity. Such a constraint is called a ‘stay upright constraint’ and its often used for sci-fi hover racing games.

As you can see, the applications of springs are limitless. The overall pattern is to design spring forces that will attract your physics simulation into the desired state and fade off to zero when this state is has been reached. In order to make sure that your physics objects don’t just oscillate around the solution but actually reach it, it is necessary to apply damping proportional to whatever physics state values are performing the evolution of the simulation towards the solution over time.

Attachment using a spring

So lets get started with an actual concrete implementation of using springs a simulation. The first thing we will implement is an attachment joint that will allow the user to click and drag a point on the cube to move it around. We will implement this by modeling a tight spring attachment between a target point and an attachment point on the body of the cube. This is effectively a ball and socket joint implemented using only spring forces and is implemented using the standard equation we are used to:

    F = -kx -bv

Where x is the vector difference between the current target point and the attachment point on the object, and v is the point velocity at the attachment point on the object. The important thing is that this velocity v being the point velocity means that it incorporates both the linear motion of the object plus any velocity at the attachment point due to angular velocity. As was shown in the previous article we can calculate this point velocity at follows:

    vpoint = vlinear + vangular cross (p - x)

Where p is the point on the rigid body and x is the center of mass of the object. Secondly, this spring and damper force is not just applied linearly, but is applied at the attachment point on the object. This means that the spring force will apply both a linear force and a torque component as follows:

    Flinear = F
    Ftorque = F cross (p - x)

The overall effect of this joint then is to bring the target and attachment points together while damping the motion of the object at the attachment point. This allows the object to move as long as remains still at the attachment. In other words the object is only allowed to move by rotating about the attachment point. Our simple ball and socket joint is now complete.

Collision response with springs

Next we will implement a basic collision response using springs. The trick here is to apply a spring and damper force that works against what we don’t want, eg. objects moving towards each other and penetrating other objects.

So we have a collision detected and the usual information is returned to the physics system ready to apply collision response. This information is typically something like:

  1. A unit length collision normal
  2. The penetration depth along the normal
  3. The physics state for each of the colliding objects at the time of collision

All this information grouped together is called a contact. Processing collision geometry and returning a series of generic contacts is a great idea because it decouples your collision response from the gritty details of collision detection.

Once we have all our contact information a simple collision response can be implemented by applying a spring-like force to the colliding objects to keep them apart:

    F = nkd - bn(n.v)

Where k and b are the spring-damper coefficients, n is the contact normal and v is the relative velocity between the two objects at the point of collision. Effectively this equation calculates a spring force that pushes out along the contact normal while reducing the relative velocity of the objects towards each other at the contact point.

Various different collision responses types can also be achieved using this equation, for example setting b to 0 gives a completely elastic collision response where all energy going into the collision returns in the bounce over time. Setting b to higher value tend to make the collision more inelastic because it removes more energy during the collision. Finally, by increasing and decreasing the spring constant k in concert with b you can make a collision that feels like anything from bouncing off a trampoline (low k and low b), to landing and sinking into quicksand (low k and high b), or landing with a splat on concrete (high k, high b).

The weakness of springs

It seems we can achieve a large variety of different collision effects using only springs and easily make joints and constraints. Its not all good news however because springs come with their own set of weaknesses which I will now explain.

The first weakness is that its difficult to tune the spring constants to get exactly the effect you want. For example, if you are attempting to model the real world physics of an object, you will need to experiment to find the spring k and b values that match the simulation. These values are usually dependent on other values of your simulation, such as the gravity constant, meaning that if you adjust gravity you’ll need to retune your springs to get the same effect. This is a pain.

The next problem is that tighter the spring k you use, the more difficult it becomes to solve the differential equation. Using an RK4 integrator sure help with this, but even with RK4 there is a fundamental limit to how large you can make your spring k before your simulation will explode. At this point you need to either decrease your timestep or reduce your spring k.

The final, and major weakness is that springs are reactive not predictive. This is a subtle point but a very important one. A joint or constraint implemented using springs only works by correcting errors after they occur, and collision response using springs requires allowing some amount of penetration before it acts to correct it and so forth. More advanced techniques exist which can solve for the forces required to constrain the physics simulation without inducing error, such as LCP solvers or iterative methods, but they are out of scope of this simple article!

Conclusion

You can use spring-like forces to model many different physical effects, and they are a lot of fun to implement.

The only downside of springs is of course that they are best used for implementing soft and springy constraints, but most of the time when you are using springs, this is exactly the effect you are looking for!


Next: Networked Physics




If you enjoyed this article please donate.

Donations offset hosting costs and encourage me to write more articles!

47 thoughts on “Spring Physics”

  1. If you model springs as an energy conversion (compression energy to kinetic energy and back again), then you can avoid any possibility of them ‘exploding’.

  2. Suppose a block(of mass m) moving on a plane collides against a spring kept longitudinally alond the plain.if v is the velocity of the block before collision , what would be the velocity after the block rebounds

  3. We are graduate students doing a term paper on collision detection. We find the format of your articles easy to understand and apply. Any chance that your article on collision detection will be out soon…a draft version sent by email would be great :).

  4. I’d love to see an implementation that uses energy instead, as per comment #1. I’ve heard programmers of racing simulations do their hard springs that way (suspension/tires).

    For a more generic method on reaching velocities and such (motors) readers should definitely check out PID controllers (proportional/integral/derivative) which can be used as a base for such things.

    Lastly, for really stiff springs I’ve used implicit integration, which can also help to keep systems from exploding (quite effectively).

  5. Hi Glenn, these articles are mint – thanks for writing them. There is reference to code for this one on springs, but I can’t find it anywhere. I’m also really keen on the collision detection stuff.

    Cheers!

  6. yeah i’m real sorry i never got around to coding a good springs example, as i pushed headlong into “zen of network physics” using the codebase — if i get some free time i’ll try to find my old code with mouse select and drag on the cube using a spring

    note that the collision detection in the network example with the cube is using springs as described in this article

    cheers

  7. Great article, thanks. If you use springs to control a collision response, they alter the acceleration fine, but what happens if the object is colliding at a fairly high speed? It would set the acceleration in the opposite direction, but it would fly straight through, since it would take a while for the velocity to reset to 0 and change direction.

    Do you have any ideas on how to tackle this issue? I don’t want my hypothetical ball flying straight through the concrete ground, if he goes a bit fast.

  8. A bit of code from my implicit spring calculation (for a wheel with stiff suspension):

    velocity.y=(velocity.y+RR_TIMESTEP*forceNonDamper.y*oneOverMass)/(1.0f+springK*oneOverMass*RR_TIMESTEP);

    Here ‘y’ is the vertical axis.
    Note that I never understood restricting explosions using energy; although I know potential and velocity energy, springs that get external input (a wheel touching the road) brings energy into the spring system, so I never quite grasped how you could limit the amount of energy flowing into it all.

    Anyway, terrific articles, they really fit nicely into my line of thinking, meaning they explain things well for me. :)

  9. hi,
    This is an excelent alternative to Impulse based collision response (i checked out your networking section and the accompanying code) as it is simple and effective (as long as the sim runs at small timesteps).

    What are the implication for multibody dynamics? I am not looking for stacking or contact resolution as the current implementation handles these in a firly effective manner, but once you end up with, say, 50 bodies, all colliding in a small area, can the spring model really handle this?
    I am guessing itterating over a scene-graph would make life easier.

  10. i dont really propose this as any sort of new alternative, its just an easy way to get a handle on the problem — google for “penalty method” and you’ll see its this same approach

    its downsides are:

    – springs are reactive, constraints are soft not hard
    – small time step requirement
    – lots of tuning required…

  11. Excellent article! Thanks alot! This article makes *alot* more sense than the other articles I have read on spring physics. I coded this in a few minutes and it worked perfectly. Previous attempts gave very ehh… interesting results. This page should really be ranking higher on Google!

  12. Hi Glenn,

    These articles are fantastic, thank you very much for explaining these topics in such comprehensive detail. I am interested in the spring response technique to collisions, but I am having difficulty understanding the particular equation you explained:

    F = nkd – bn(n.v)

    Whilst this is a nice solution to the problem at hand, surely the greater the velocities of the objects, the smaller the force will end up? For example a fixed flat surface, and a ball bouncing on it, if the ball is travelling downwards towards the surface faster, the force response would be smaller than if the ball was travelling slower toward it, which would seem to be the opposite of what you’d expect? Maybe I am missing something, but thank you for these fantastic resources all the same!!

  13. its a vector quantity, so no, the velocity will not be smaller as the object moves faster towards the surface, it will in fact be larger, and proportional – just reflected *away* from the surface so it bounces

    cheers

  14. That was a quick response. Thank you so much for all the help.

    I think I may have been getting confused because I had too low of a moment of inertia in my simulation so it looked like the object was spinning too much.

  15. Hi,

    If both ends of the spring can move, how would you manage the caching of the inverse spring force, after you calculated it for one end. Would you cache the results of all the 4 runge kutta integration steps and reuse them during integration of the other end, or is just the force of the currtent state reuseable?

    thanks

    1. When dealing with multiple bodies attached to each other would you argue for or against moving neighboring nodes for calculating each RK4 step?

      1. I found that advancing all bodies together in each RK4 substep tends to increase the total energy of the system (i.e. explode) more quickly than advancing each body through all RK4 substeps separately. However, advancing each body through all RK4 substeps separately seems to lead to higher systematic errors. For example, the center of mass of a two-mass oscillator tends to float in the direction of the mass which is integrated last.

        Based on what I found, I personally prefer advancing each body through all substeps separately: it’s easier to code and seems to be less prone to explosions in complex systems.

  16. Great series of articles. thanks!

    However, the springs article seems to be the only one that you didn’t offer the source code with it. Is it available? I find it interesting to be able to walk through the code – even though I am not a C++ guy anymore (or at least, not frequently). I have ported the others to my Java/Eclipse framework, though.

    TIA

      1. Ah, I hadn’t actually read that article yet as my interest in networking is limited. I’ll check it out now… :-) Thanks again. And to second (or third) the others on these threads, I would be interested in the article on collisions.

        And BTW, I did donate, though not enough for two weeks of your spare time! :-)

  17. Hi!
    I want to point out that, actually, your description of equation on springs and dampers is completely wrong. F= -kx .where x is not LENGTH of the string but actually the difference(with sign) between length of relaxed spring and the spring stretched/squeezed(x = deformation). So basically if spring is relaxed the force is F= -k *0 = 0 ; and when lets say its stretched 10 centimetres the F= -k*0,1= -0,1k.
    so for k =1;
    normal spring x=0;
    stretched spring x= 0,1m : F=-0,1 force is negative to the force you use to stretch.
    squeezed spring x=-0,1m : F=0,1 force is again negative to the force you stretch with, but actually you squeeze, so it want to be relaxed again.

    BTW. Really great articles!

  18. You might want to explore my App – 4 springs and one mass –
    http://www.itunes.com/app/springsnthingslite

    It uses the Euler-Cromer algorithm which is much better than just Euler because it conserves energy when there is no damping. Cromer tells us to take a half step in approximating the velocity. The full version of Springs’nThings lets you adjust spring damping, pendulum damping, mass, etc.

    Hope your readers (those with an iPhone/iPad/ITouch) enjoy it.

    Peter

  19. Hi Glenn, I like your article. I’ll like to know if you have any idea on how to calculate Mechanical damping of a mass spring damper system?

  20. I’m trying to build a 2D version of your cube example. Your formulas use cross product which I thought was only for 3D.

    I knew I needed a way to “combine” angular velocity with xy movement, but I didn’t know where to begin. Basically I have a 2D spaceship which the player can steer with a thumbstick. Your cube example seemed like a good starting point but given my lack of experience I may be barking up the wrong tree.

    1. It’s much easier in 2D. You can just have x,y position, x,y velocity and a single angle for orientation and one value for rotational velocity which is a scalar (you decide if the rotation is clockwise or counter-clockwise rads per-second)

      cheers

      1. Here is a hint: Because the rotation may only be a single value you can view this as a scalar either INTO the screen or OUT of the screen (negative or positive). +/- corresponds to clockwise or counter-clockwise motion.

        Also, see this:

        http://en.wikipedia.org/wiki/Cross_product#Geometric_meaning

        The magnitude of the cross product is |a||b|sin(theta)

        You can use this to simplify the equation for taking the impulse/force and working out what angular component there is, without the cross product. Write it down on paper and you should see it simplifies down to something that works in 2D.

        cheers

  21. Hi,how to handle collidion between springs?The mass point has mass, if we only consider the mas, the springs may be go through each other.If we consider the line between two mass point, how to cacluate the fore to apply to the two mass point?

    1. Massless springs in series and parallel add like capacitors in series and parallel, IF AND ONLY IF there is nothing else internal to the spring network. Generally, you don’t want this, however.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Glenn Fiedler's Game Development Articles and Tutorials