Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Geek Culture / The keys to a physics engine.

Author
Message
flashing snall
19
Years of Service
User Offline
Joined: 8th Oct 2005
Location: Boston
Posted: 23rd Nov 2010 22:22 Edited at: 8th Dec 2010 03:58
EDIT: Rotation and dynamics is a go. If you guys are interested in the how, let me know.




I say to you, Yo.
Its been awhile since Ive been by TGC, but I figured I'd stop by and say hello, and share a neat little physics project Im working on. Its not in DBP, because I've found that object oriented languages work better for these massive scale projects.

Anyhoo, if you would like to take a physics journey with me, and explore the secrets of the universe, than read along! If you think physics is stupid and have no interest whatsoever in learning fun and exiting new things, then shove off.

I have set out to construct a physics engine to be able to boot up for any project I want to. The language I chose was C# utilizing the xna framework. Basically, I started by writing a polygon class, made up of Line classes, made up in turn by Vector2 classes (I actually rewrote the class as a Point class, but I think that was a stupid move). The first hurtle was to get polygon collision working, which wasn't too too bad. Ill post the code, but for those of you who don't read C lingo, Ill explain as well.

This is a method that determines if two line segments are intersecting. Using this, its pretty simple to see if a polygon made up of lines are intersecting. You just loop through all the lines in each one, checking for collision with the lines of the other.
The way this works, is to simply call a line by its definition of y = mx+b. Now, if you take one line's x, and plug it into the other line's equation, and the outcome is similar to what that equation would output with its own x, then the lines are intersecting. Ive given mine a .0001 margin of error I think, just by subtracting the test value from the real value, and if their difference is zero, then they are the same, but if they're only .00001 off, then there close enough.
Then you can just take the x and y coord and see if they lay withing the line segment bounds.
This method is really cool because there is no looping at all, which means its not that hard on the cpu. There is a special case for vertical lines at the bottom, because vertical lines have a slope of infinity.


Now that my polygons can intersect with one another, I need a good way to bounce them off each other. I started testing this using discs and such, or hockey pucks (as I like to call them). When two hockey pucks hit each other, they should bounce off at odd angles, sort of like pool balls. This is where the physics comes in.

in the simple case, lets ignore spinning, because that gets really funky. So for right now, were just going to be concerned with translational (linear) motion. The key to solving these collision problems is momentum! Momentum is a fundamental property of an object, and it is solved by multiplying the mass by the velocity. The symbol for momentum is P.
P = mv
The wonderful thing about momentum is that within a system, it is ALWAYS conserved. That is to say, the initial sum of momentum equals the final sum of momentum. So if we have two discs, then this equation stands true.
(initial velocities are noted with an 'i' and finals with an 'f')
m1v1i + m2v2i = m1v1f + m2v2f
This equation gives us two unknowns, the final velocities of both objects. We'll need another equation to solve for it. We can turn to another awesome part of physics to get it.
Like momentum, within a system, Energy is ALWAYS conserved. In our case, were going to ignore friction and say that no energy is lost during the collision. In this case, there is no gravity either, so the only energy quantity we care about is the energy of motion, which is called kinetic energy. Kinetic energy (K) is defined by
K = .5mv^2
so, using the same principle as momentum, we can say that
.5m1v1i^2 + .5m2v2i^2 = .5 m1v1f^2 + .5m2v2f^2
and now we can cancel out the .5 because it is in every term, leaving us with two equations.

m1v1i^2 + m2v2i^2 = m1v1f^2 + m2v2f^2
m1v1i + m2v2i = m1v1f + m2v2f

Looky Looky! Two equations, two unknowns! Now we should be able to substitute and solve out for V2f and V1f. However, the algebra is horribly nasty, so Ill just take a shortcut through wolframalpha.com and tell you that the contents of the code box are the two equations in C# speak. They should be pretty easy to read, but if you don't know, the e1. or the e2. means object 1's whatever, or object 2's whatever.

(for people who know C# and xna, I took out the variable declarations for readability, but they are Vector2's)


The above gives us a great way to find the final MAGNITUDE of the final velocity, but we still don't know in what direction that magnitude will point. So know we need a bit more physics and a bit of geometry to figure out in what direction the discs will bounce off of each other.
We can find the direction of the velocity because we know that it will have the same direction as the final momentum. Momentum and velocities are both vectors, and since p = mv, and mass is just a scalar, the direction of p and v must be equal. The final momentum can be found by this equation
pf = pi + deltaP.
All that means is that the final momentum is equal to the initial momentum PLUS the change in momentum.
Now let me clue you in a little tid bit. The direction of deltaP (change in momentum) is something we can solve for with a bit of geometry. We know that it must point PERPENDICULAR to the TANGENT of collision. That sounds a bit harsh, but its not that bad. There is a tangent of collision, which means the line that only touches each object ones, and passes through the intersection point. So if you dropped a ball on the floor, the tangent of collision would run Parrnell to the floor. The way to find this line, or really just the angle of this line, because that's all we need from it, is to find the intersection points between the object, and draw a line between them. You can draw it out on paper, but you'll see that drawing a line between the two points of intersection for two polygons will give the tangent. And consequently, the direction of the deltaP will be perpendicular to it. To find out which way its going to be perpendicular, as in, weather to add 90 degrees, or subtract 90 degrees, just comes down to looking at the lines slope and if its negative, subtracting, and if its positive, adding. The trick is that each object needs its own tangent of collision, because they should be opposite of one another. As in, one would be 0, and the other would be 180.
Now that we know the direction of the deltaP, we can find its magnitude via a little math. Follow along, its not that complex.
(note, the d means "delta", and is in no way talking about calc)
pf = mvf
pi = mvi
dp = pf - pi = mvf - mvi = m(vf-vi)
dv = vf - vi
dp = mdv
Now we can apply the magnitude we just found to the direction we found earlier, and BAM, we got our change in momentum. Now it stands to reason that if we know the initial momentum, and change in momentum, then the final momentum should be a piece a cake to solve for. And when we solve for it, it will give us a direction, since both the initial and the change in momentum have directions.
Now we just take the direction of the change in momentum, and apply it to our previously found velocities.

AND PRESTO!

The discs are now acting like fancy pool balls, and flying off of each other at fantastic angles.

The whole business about tangent of collision will make sure that if you heave a disc at a rectangle, then the correct bounce will also occur.

The next big step is to bring in spinning.
... But Im still working that one out myself, so if you guys have any thoughts, let me know, and when I figure it out, Ill let YOU know.

So I hope that you enjoyed that fun little spin through physics land. When I get spinning up and running, Ill post a tech demo of my engine, because at that point, I think it'll almost be done. Just need to work in gravity (easy as pie), and pivot points (not as easy).

Tootals.

The Wilderbeast
19
Years of Service
User Offline
Joined: 14th Nov 2005
Location: UK
Posted: 23rd Nov 2010 23:17
That was fascinating. Since studying physics I had always contemplated writing a physics engine - the mathematics / physics behind it is fairly easy. But I couldn't figure out how to work out which way two objects would ricochet after a collision - so thanks for clearing that one up xD

flashing snall
19
Years of Service
User Offline
Joined: 8th Oct 2005
Location: Boston
Posted: 23rd Nov 2010 23:40
Thanks. Im actually having a bit of trouble figuring out the perpendicular thing off the tangent. I thought I had it figured out, but I guess not.

flashing snall
19
Years of Service
User Offline
Joined: 8th Oct 2005
Location: Boston
Posted: 24th Nov 2010 00:39
Scratch that, I just had a fun geometry party, and I found the answer. Have to be careful with negatives and such. Im sure this is a clunky way of doing it, but oh well, it serves its purpose.

This is the part of the code that takes the tangent angle and converts it into the deltaP angle.


and now I get to go make pies!

The Wilderbeast
19
Years of Service
User Offline
Joined: 14th Nov 2005
Location: UK
Posted: 24th Nov 2010 08:23
Your tangent is just going to be the negative reciprocal of the gradient. Getting your angle from that should be fairly straight forward.

flashing snall
19
Years of Service
User Offline
Joined: 8th Oct 2005
Location: Boston
Posted: 25th Nov 2010 18:08
Ah, okay.

So as far as the angular momentum stuff goes, I think I have taken a step in the right direction.

linear momentum is always conserved, and angular momentum is always conserved as well. So I figured I could treat them like separate cases, and thats what Im doing.

when going to angular motion, there are tuns of new symbols to represent different things, but really, they all have alialises with linear variables.
x is theta, mass is inertia, velocity is omega (w), acceleration is alpha , and so on. Angular momentum (L) is defined by
L = Iw
and then the kinetic energy of a spinning object is defined by
K = .5 Iw^2
and those look strikingly similar to the linear momentum equations I got earlier, so I just wrote out the same equations, but subbed inertia in for mass, and omega in for velocity, and said that they would give me my final omegas.

But how does spinning translate into linear motion? I currently have decided to just add a bit of stuff onto the final linear velocity, like so...
Vf1 += e2.omega * r;
where r is the distance between the two objects. IT should technically be the distance of closest approach/lever arm/effective r or whatever you want to call it.

But using that, things seem to work so far. Ill do a little bit more testing, and then post the outcome. If anyone has any questions, let me know. Id love to explain it again if I wasnt clear.

The Wilderbeast
19
Years of Service
User Offline
Joined: 14th Nov 2005
Location: UK
Posted: 25th Nov 2010 19:11
Angular momentum is a bit beyond me I'm afraid, my knowledge of the newtonian world only takes me as far as Simple Harmonic Motion in that respect.

flashing snall
19
Years of Service
User Offline
Joined: 8th Oct 2005
Location: Boston
Posted: 5th Dec 2010 01:20
This translation from kinetic to rotational energy or vice versa is killing me.

If anyone has any ideas, please PLEASE PLEASE.

I am so lost. My professor at school after twenty minutes of trying this said to me "Damn, this is hard."
gr.

flashing snall
19
Years of Service
User Offline
Joined: 8th Oct 2005
Location: Boston
Posted: 8th Dec 2010 04:06
not to double post.... but.... bump. (dont hate)
Check the top of the page.

Login to post a reply

Server time is: 2025-05-30 07:59:07
Your offset time is: 2025-05-30 07:59:07