2D Rigid Body Rope Physics

I have a simple game created where I can walk side-to-side, and jump.
I have implemented a mechanic to shoot out a “string” or “rope” and it will attach to the sides of the screen.
I have very basic physics in place for the character (a white square), but this does not include mass yet. (I’m unsure whether I’ll actually need mass or not for the rope physics).
Eventually, I would like to have a 10-15 segment rope that acts realistically, but for game design purposes, I’ve decided to use a rigid-body rope for now.

My problem is that I just can’t find any resources online about the math involved in such physics.
The rope should have a fixed length, and should swing from the point of attachment on the screen.

P.S. - I have no interest in using a pre-made physics engine, unless the API docs have source code of their math.

Any help on the subject is much appreciated! :smiley: Thanks in advance!
~QuicK

box2D is opensource so you could always try to pick that apart

also http://chrishecker.com/Rigid_body_dynamics has a ton of good information made for beginners i highly recommend it

Thank you, I’ll check it out!

Well I have no idea about simulating a fluid rope, but a rigid strut type thing is simple enough. Here is a little I worked out scribbling on paper (which means it ain’t my fault if something is wrong, it is the paper’s fault).

So as with most angular motion questions, the maths is easier if you work in terms of angles. This might make the simulation harder or it might not, but it is what I am doing here.

So taking theta to be the angle between the horizontal and the rope, then the angle between the vertical and the rope is 90 - theta, and hence the angle between the normal and the vertical is also theta.

Then we can say that the magnitude of the resultant acceleration on the body, at = g * cos(theta)

Then a simple matter of using the formula for angular acceleration to give angular acceleration, alpha = g * cos(theta) / r where r is the length of the rope.

Not sure how helpful this will be. If you are using euler integration in your simulation then you’re sorted (apart from maybe converting it into a more linear thing. If that is the case I’d be happy to help).

hmm…perhaps this is a bit above my head with the physics aspects. I understand what you are talking about with theta, but what is the “normal” vector that you list?

In order to implement your solution, I’ll need to rotate the acceleration on the object?

If you could put together a quick example for me in either pseudo-code or a working example, that would be greatly appreciated.

OK, I will give you a quick example, but I will also explain myself a bit which I think will help more. And sorry, I forget that pretty basic mechanics generally aren’t taught in schools (in England I had to do an A-Level in physics to be taught about angular velocity and even then it was only very basic).

Angular velocity is a bit of a hard thing to get your head around if you aren’t used to it. So you can think of velocity as the speed and direction in which position is changing (rate of change of position if you’re big on calculus) and angular velocity is the speed and direction (in this context clockwise or anticlockwise) in which an angle is changing. That angle can be that of a body rotating on its centre of mass, or that of a body in circular motion about a point (as we have here). So what velocity is to position, angular velocity is to angle and what acceleration is to velocity, angular acceleration is to angular velocity.

So a “normal” to a line is a direction which is perpendicular to that line. (In 3D you can also get a normal to a face, which is a direction perpendicular to that face). Example:

http://images.tutorvista.com/cms/images/67/perpendicular-line-definition.png

So if we have a rope with a guy on the end, then the normal to the rope is the tangent to the circular path the guy is going to swing in. Ie it is the direction he will travel in at that moment in time which we call the tangential velocity. (aT in the previous post stood for tangential acceleration).

In that diagram, v is the tangential velocity. Ignore the centripetal force thing.

So now, my code example. I’m going to write a SwingingBody class with an update() method which takes the delta time for the current frame as a parameter. It uses euler integration to compute the current angle of swing. Things I’m leaving out are a way to render it and any collision detection/handling.


public class SwingingBody {
    public static final float g = 9.81; //Constant for average gravitational acceleration at the surface of the Earth. 

    private float angle = 0; //The angle between the rope and the horizontal.
    private float av = 0; //angular velocity
    private float r; //The radius of the swing - the length of the rope.

    public void update(float delta) {
        float aa = g * GMath.cos(angle) / r;
        av += ( aa * delta );
        angle += ( av * delta );
    }
}

Three notes about this code:

  1. I have used a function called GMath.cos(), this is meant to be a regular cos function accept that it takes a float as a parameter and returns a float as well. I don’t know what framework you’re using so I just used my own framework.

  2. Generally we work with delta in milliseconds, however the constant for g I have given is in metres per second squared. So you must either divide delta by 1000 to get it in seconds or divide g by 1000,000 to get it in metres per millisecond squared.

  3. Sorry about the fancy definition for g, I’m a physicist at heart.

Hope this helps.
Quew8

Oh, wow! That makes a lot more sense haha thank you :slight_smile: I’ll take this concept and see what I can do with it.

One last question though.

The way I’m currently moving my player object includes absolutely no angles, only position, velocity, and acceleration.

Should I be using angular velocity to move the player in all instances or only when I need to calculate the position of the rope?

Great.

In answer, no I would keep things in terms of position and linear velocity and make this a special case scenario. I have an in-progress 3D space sim where I have to work with linear and angular (about the centre of mass) motion to model forces properly, but that is really the only time you would have to work with angular motion under “normal” circumstances. There is certainly no sense in you doing it here.

One more thing I would say is that make sure the angle in this code is either always clockwise or always anti-clockwise. I can’t work it out in my head but I’m 80% sure that you could end up with someone swinging to the top instead of the bottom.

Edit: No I’m wrong. cos(theta) == cos(360 - theta) since cos() is symmetrical about x = 180. So it doesn’t matter whether it’s clockwise sometimes and not others.

Not sure if this model would work in your case but I’m posting this as this is what i used when I made one:

http://freespace.virgin.net/hugo.elias/models/m_string.htm

Thank you again @quew8 :smiley:

@relminator

In that model, do you know what the extension represents? Also, what the “Normal_Length” variable is? As I remember it, a normal’s length is always 1 soo…not sure what else it could be.

P.S. - @quew8 how do I go about implementing the angular acceleration and angular velocity into the position of the vector?
I believe I have calculated all of the variables correctly, I’m just unsure of how to actually apply them.

Sure, so you use angular acceleration and velocity to calculate the angle as in my code snippet, then you can use trig to work out the actual position.

Essentially

px = cx + r * cos(theta)
py = cy - r * sin(theta)

Where p is the position of the swinging body, c is the centre of the swing where the rope is attached, r is the length of the rope and theta is the angle.

Edit: Fixed, because stuff falls down, not up.

OK, I just felt like trying this out for myself; really there is something very satisfying at watching a ball swing back and forth on a string. So here: http://pastebin.java-gaming.org/d0bb2981a0e14 (I don’t know how to embed JGO pastebins). I made it using LWJGL so if you don’t use LWJGL, then you won’t have the libraries and natives to run it and you probably won’t understand the rendering parts of it. But the simulation bits should still help.

Now as soon as I had it, I realized that the thing just kept swinging infinitely so I had to add in a little (very) simplistic friction. That is the " - ( av * FRICTION_COEFFICIENT / mass )" term in the SwingingBody.update() method. That friction bit is the only reason the mass of the body affects the motion.

One last thing - it is very crude in places. I was trying to do it quickly, and shortly whilst making it self-contained. Sorry.

Awesome! Thank you so much! You’ve been extremely helpful.

Not only did your example project allow me to further test, but those 2 simple position algorithms helped me fix my own implementation :slight_smile:

So, I’ve successfully implemented the rigid rope. I was wondering if there is an easy way to calculate the linear x and y velocities of the point of the rope that is swinging?

(aside from the delta position algorithm)

There certainly is.

vx = w * cos(theta)
vy = -w * sin(theta)

Where w is angular velocity and v is tangential velocity. You may notice that position and angle share the same relationship as angular velocity and velocity. Just a little aside because it makes me smile to see maths work.