Home > Android, Games Programming, HTML5, My Thoughts, XNA > Simple Spring Physics

Simple Spring Physics

A few weeks ago (during exams period 😛 ) I was playing with spring physics, it turned out to be easy to implement and the results were cool enough for me to write a demo in Android, Microsoft XNA, and Javascript :D.

SpringLab img

Before I talk too much, here see the results for yourself, this is the web version :  SpringLab Web Version.

Reminds you of World of Goo 😀 ?

I came across this tutorial, from which I learned this lovely vector equation:

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

I applied it to 2D springs and it gave amazing results especially when having a mesh of nodes connected through springs! the mesh looks like a 2D cloth simulation!.

Essentially I update all the springs (code below) then update the nodes (adding acceleration to velocity, velocity to position)

 /// <summary>
/// Update physics (Applies force and adds to the acceleration of connected nodes)
/// </summary>
public void Update()
{
	//    F = -k(|x|-d)(x/|x|) - bv
	float xAbs = Vector2.Distance(node1.p, node2.p);
	if (isString && xAbs < d) return;

	Vector2 F1 = -k * (xAbs - d) * (Vector2.Normalize(node2.p - node1.p) / xAbs) - b * (node1.v - node2.v);
	Vector2 F2 = -k * (xAbs - d) * (Vector2.Normalize(node1.p - node2.p) / xAbs) - b * (node2.v - node1.v);

	// Nans propagate through the nodes network, we don't want that
	if (F1.IsNan() || F2.IsNan()) return;

	// Add acceleration. Updating velocity\positions should happen after all springs are updated
	node1.a += F1 / node1.m;
	node2.a += F2 / node2.m;
}

I added many features like dragging and creating nodes and springs and changing parameters at runtime.

I made a short video to demonstrate what you can do using this simple equation, I hope you watch it 🙂 it took some time to make it:


XNA Version:

Why did I use a dying technology? because XNA allowed me to make a prototype really fast!.

Anyway, the XNA version is faster and smoother than the web version, you can try it here:

SpringLab PC (60KB) – you will need to install Microsoft XNA Framework Redistributable 4.0 (6.7MB) if you don’t have XNA Game Studio installed.

SpringLab PC Source (78 KB) – XNA4, VisualStudio 2010

If you want to take a look at the source code of the project I recommend this source code, since it’s much easier to read than the Java or the Javascript version.

HTML5 Version:

I’m not sure if it’s mouthful to say “HTML5 version” :D, anyway no images are used in this version since all the rendering is done through the canvas object.

I had to write this version or otherwise no one will try the app, people become less interested when it comes to downloading files ;), the web version is much slower than the other two versions, I’m not sure why but if you can help me increase the performance I’ll be happy to hear from you.

SpringLabMin.html (10KB) – Javascript code minified using jscompress.com

SpringLab HTML5 Source.zip (12KB) – Aptana Studio project

I tried the web version on my Android, both logic and rendering worked perfectly but there’s always this scrolling and zooming issues with phone browsers, If you want to move a node you’ll scroll the page and it won’t work, event handling tends to be more difficult on mobile phone browser.

Android Version:

I made this version after finishing both the web version and the desktop one, the best thing about this version is the multi-touch support :D, I made sure to make the app support as many fingers as your device can recognize :D.

You’ll need an Android 2.2+ to try this app (sorry if you are from the other 0.2%!)

SpringLab.apk (216 KB)  – Android 2.2+

Works on BlueStacks too :).

SpringLab Android Source.zip (460 KB) – Eclipse project

“Was it worth wasting your time implementing three different versions?”

To be honest: I’m not sure, I mean if you’re making a game you’ll have to make sure you support many platforms, I consider the time I spent on this project as some sort of training for the future :).

One thing worth mentioning: creating a working version didn’t take much time, most time was spent on the small details to make each version look better.

I hope you like it 🙂 , you can do much with simple spring physics, the equation above works on 3D too.

  1. Kelly
    20/08/2013 at 1:03 am

    Be aware that jscompress is outdated and has broken functionality currently. The file combine feature has been broken for a long time now. They are stuck on a outdated UglifyJS1 version.

    I found a similar tool at http://www.blimptontech.com it uses UglifyJS2 and all the features work, gets regularly updated. It has become my go to free online tool now.

    • Fuchs
      20/08/2013 at 10:55 pm

      Thanks for the info!, I’m not used to web development, I used jscompress because it appeared on the first page of Google.

  2. timtrod
    14/10/2015 at 1:19 am

    In your code, when updating node positions, you do this:

    this.v.mult(0.97);
    this.a.mult(0.3);

    Why is this multiplier necessary? If I remove it, the nodes go crazy, so it’s obviously critical to the whole thing. And why didn’t you explain it in the blog post or with a comment? Do you understand why it’s needed? If so, please explain!

  3. timtrod
    14/10/2015 at 1:24 am

    Ok, I’ve figured out the multiplication factor here.

    You can essentially think of it as air resistance or some sort of friction, like the friction of the molecules moving inside the spring. Without it, the springs behave as if there is no friction, so their wild behavior (at least in my simulation, not yours) would actually be correct in space in a frictionless environment. But there is friction, so the whole system loses energy over time. The spring formula doesn’t seem to take that into account with multiple springs. This is critical to the entire process and you really should explain it!!

  4. deblocker
    02/01/2017 at 6:09 pm

    Great post! I’m very interested in your project. Do you have an example with springs among rectangular meshes?

    • Fuchs
      03/01/2017 at 2:48 am

      Thanks 🙂
      You can try and create it your self, you just need four points
      p1(x,y) p2(x+20, y)
      p3(x, y+20) p4(x+20, y+20)

      Then simply attach springs between them. It doesn’t matter how you start connecting the points. You can create springs like this
      spring1(p1, p2)
      spring2(p2, p4)
      spring3(p4, p3)
      spring4(p3, p1)
      spring5(p1, p4)
      spring6(p2, p3)

  5. serge
    19/02/2017 at 7:01 am

    Hello from the year 2017!

    Just thought I’d drop by to say that the attached code sample (XNA) you provided is fantastic!

    Very well structured and easily readable.

    Even trying to get this to run with MonoGame3.5 + VS2015 was a breeze!

    Kudos

    • Fuchs
      19/02/2017 at 6:42 pm

      Wow 😀 , thanks for the positive feedback, I’m glad you liked it 🙂

  1. No trackbacks yet.

Leave a Reply to Fuchs Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: