Builderboy's Physics Lessons, Part V: Single Segmented Rope Physics

Submitted By: Builderboy Date: June 14, 2011, 03:58:19 pm Views: 1448

Single Segmented Rope Physics

   The situation is always the same, you are making your physics puzzle game that may or may not be a platformer, you want to add in a new game element, but you can't think of anything to add!  Maybe you want to add in some sort of rope element, but how in the world could we do this fast and efficiently?  Well this tutorial is going to teach you how to make a Single Segmented Force Based Rope Physics engine :D  That might sound complicated but lets break it down:

1) Single Segmented

    What single segmented means is that your rope will consist of only a single segment.  What this means is that we will only simulate the start and end of the rope, none of the stuff in the middle where the rope bends or whatnot.  Since one end of the rope is going to be fixed to a wall, in this tutorial we will only be simulating the object that is attached to the end of the rope.  When you go to display the rope however, you don't have to simply draw a line between the anchor and the object, you can get creative and do fancy things, but that is outside this tutorial.

2) Force Based

    There are many types of physics engines, and when combining them to create complicated effects, weird things can start to happen.  If one part of the physics engine devoted to rope physics moves an object without checking the other parts, it might accidentally move it into a wall or another object!  For this reason, the only thing this physics engine will do is impart forces onto the object, it will not move them.  We are also going to be assuming this rope is infinitely strong, and we will be ignoring the mass of the object.  By using only a force based engine, this gives us the highest possibility that this code will be able to be implemented into your existing engine.

3) The Conecpt

    So what happens to an object that is attached to a string?  What forces are exerted on it?  Before we can answer those questions, we need to decide how to define the string itself.  It needs an anchor point, and a length, so we will use three variables X,Y and L, to represent these.  We also need to use certain variables from our object, such as its position (I,J) and velocity (A,B).
 
Whenever the distance D from the object to the anchor is less than the length, we know that the rope is not going to be taught, and therefor cannot be imparting any force on the ball.  We could calculate the distance using the pythagorean theorem:

Code: [Select]
Sqrt((X-I)^2+(Y-J)^2)=D

But that uses a square root, and those are slow and sad.  Instead, we are going to square both sizes of the equation, since squaring is fast and happy!

Code: [Select]
(X-I)*2+(Y-J)^2=D^2

So now when we compare D to L, we will actually be comparing D^2 to L^2.  The size difference doesnt matter, since are only seeing if D is greater than L.  If you are using a x256 precision engine (which you should be :P) you can use this piece of code to find the distance in pixels (not x256!)

Code: [Select]
abs(X-I)->r1*^r1+(abs(Y-J)->r1*^r1)->D

So now we can tell if the object is pulling the string taught, or if it is letting it slack.  Obviously if it is slack (D=L) that we start needing to apply a force.  

When a ball is moving out of the allowable ring of movement that the string allows, the first thing we need to do is eliminate the velocity that is taking it outside the ring.  This does not mean setting the velocity to 0.  This does also not mean we negate the velocity.  Imagine this:  The ball is falling straight down with the string above it.  When the string pulls taught, the ball will be yanked back up again and lose almost all velocity very quickly.  But if you drop it from an angle, off to the side, it will lose a little speed, but most of it will be transfered into a pendulum motion.  In a sense, all of the velocity that is directed out of the ring is being removed, and anything that is in line with the ring (tangential, its the motions it moves in when it swings) is kept.  Now this is a bit tricky to do, so bear with me here:

I-X//L->N
J-Y//L->O

This finds the Normal Vector of the string.  The math behind it isn't that important except that you know that it points in the same direction as the string, from base to object.  This will be important in determining how much velocity to remove, and from what direction to remove it from.  The string is the only thing that can take velocity from the object, and as such, it can only affect the object in the same direction the string is pointing.  The significance of this is that any change in the velocity of the object will be a multiple of this Normal Vector!  All that is left is to find this coefficient!

That coefficient just so happens to be the dot product of the objects velocity and the ropes normal vector.  A**N + (B**O)*-1->K
Spoiler For Spoiler:
Yeah, this isn't the 100% right dot product.  Technically speaking we would have to multiply two Normal Vectors, and AB is not normal.  But since we are going to be multiplying by AB anyways, we just combine the steps by not dividing and multiplying by AB :P I put this in a spoiler just because its pretty involved vector physics and not needed for the tutorial.  Similarly, multiplying by -1 isn't something that is done in a dot product, but is done later twice so i moved it back here so we only had to do it once :)


Now we need to do a quick test.  On the off chance that the ball is outside L, but actually moving *towards* the rope, K will be positive, and you don't want to affect the ball in this case.

Code: [Select]
If K<<0

Now all that is left to do is to add the velocity to the object!

Code: [Select]
K**N+A->A
K**O+B->B


Note that this will remove all velocity that is taking the ball outside the ring of string; stop it dead.  Sometimes this is undesired, so you can make it pull a little bit more and give the string a little "bounce"

Code: [Select]
K**N*3//2+A->A
K**O*3//2+B->B


And thats it!  You are done!  This is what the final result should look like when you piece all this together:
(Note that L^2 has been precomputed and put into M)

Code: [Select]
If abs(X-I)->r1*^r1+(abs(Y-J)->r1*^r1)I-X//L->N
J-Y//L->O
A**N+(B**O)*-1->K
If K<<0
K**N*3//2+A->A
K**O*3//2+B->B
End
End


And this is what it should look like when implemented into a simple program!


Discussion topic (and possibly updates)

Rating: This article has not been rated yet.

Comments



Powered By SMF Articles by CreateAForum.com