51 Replies  9708 Views  Last Post: 25 June 2012  09:56 PM
#16
Re: Implementing 2D Physics
Posted 11 May 2012  08:31 AM
Also I'm sure you have probably figured out the terminal velocity already but just check it for > terminal velocity and < terminalvelocity, if it breaks one of these then just set it correctly to either positive or negative terminal velocity.
#17
Re: Implementing 2D Physics
Posted 11 May 2012  10:15 AM
DanielLeone, on 11 May 2012  01:20 AM, said:
Wow, my post are getting nearly as long as one of BBecks .
The do get really long, don't they.
I haven't been replying for a couple of reason. The main one is I've really been focusing on 3D and haven't written hardly any code in XNA that's 2D. So, I don't read 2D code half as well as a lot of people on here. I almost have to have all the code and put it in the debugger to find problems. Where as a lot of the experienced coders on here spot issues real quick.
Plus, I'm also busy working on trying to put some stuff together for a tutorial.
But anyway, I'm real happy if you and everyone else get something useful out of all my "ramblings".
Now about the issue. I'm hearing you basically say you want to get weight/mass involved in this whole thing because it's just not that realistic to have everything basically weigh the same amount and that sort of thing. You want to know how mass comes into the picture with movement.
It basically goes back to my original post on this topic.
Force = Mass * Acceleration
If you're good with algebra, you will immediately realize that that means
Acceleration = Force / Mass
When I talked about applying gravity, I said that you have a vector that represents the objects current velocity. It will continue at that same velocity forever until something changes it. In the previous example that change came from applying the acceleration of gravity as a downward vector every frame.
I mentioned that gravity is not the only acceleration out there, and that an acceleration could be applied horizontally.
So, now let's talk about attaching a "rocket engine" to our ball. It's affected by gravity through the methods I described earlier.
Now what you want is to also allow it to be affected by the acceleration of our "rocket engine". The rocket engine is going to be a vector that's applied just like gravity. The difference is that it's not going to always point down; it could point absolutely any 2D direction. It's not going to be applied every frame but only when the rocket engine is "on" we'll apply it every frame. And we have to calculate it's acceleration value.
There are a couple ways you could handle on and off for the rocket engine. You probably want to assign a keyboard key for it. You could just apply the rocket's vector every frame when the key is down. Or you could basically have a flag/state variable that is a bool for "engine on" true or false. Then you would apply the rocket's vector whenever it's on, but still probably every frame. Ok. So I think we're good there.
The next thing is to calculate the acceleration that the rocket applies. Like a lot of things in Physics, you could try to get super realistic and get into the chemical reactions going on in a rocket engine. But, we're not gonna worry about that. We're looking for something realistic but still "high level".
So, we're going to represent the rocket's power with Force. The rocket engine is going to have a certain amount of force that it pushes with. We're just going to arbitrarialy assign a number here. We're not going to worry about getting super realistic with the amount of force but just throw a number out there.
If we're working with meters, we probably want to measure our force using Newtons as our unit of force.
http://en.wikipedia....i/Newton_(unit)
This is where mass comes in. Going back to our formula, we have:
Acceleration = Force/Mass
So to calculate our acceleration vector, we're going to make it's length be our force in newtons divided by the mass of the object that the rocket is pushing  our ball. And we need the vector to point in the direction that the force is applied (the direction the rocket engine is pointed in).
You're probably going to have to have some sort of control over what direction the rocket engine is facing (your rocket's acceleration vector). You're going to need to assign some keyboard values to change the direction of the rocket's acceleration vector. For simplicity and testing, you may want to hardwire the rocket to point upwards. Since that's against gravity, that will give you a way to overcome gravity.
Once you get more advanced and are ready to have the rocket point in diferent directions, you are going to want to rotate the rocket's acceleration vector to control the engine facing direction. Even then you are still just going to add this acceleration vector to the velocity vector, just like adding the gravity vector. But starting out, just keep the vector (and your engines pointed straight up).
So, every frame we're applying the gravity vector, and now we'll also be applying the rocket's acceleration vector every frame that the engine is "on".
Let me kind of write some "pseudocode" to give you a rough idea of how you might code this. I'm doing this off the top of my head, so don't think this will work "as written", just use it to get an idea. This is not "tested" code.
Vector2 BallsVelocity = Vector2.Zero; //Ball starts at rest Vector2 BallsPosition = ; //Whereever you want the ball to start at float BallsMass = 2; //ball's mass in kilograms (we assume mass and weight are the same thing because that's easier). Vector2 Gravity = new Vector2(0f,0.1635); //I think this is the gravitational acceleration per frame... I think. Vector2 EngineImpulse = new Vector2(0f, 0.2f); //Engine's max force which we are setting to 0.2 Newtons straight up. Vector2 EngineAcceleration = Vector2.Zero; float EngineThrotle = 1.0f; //1.0=100%. 0.5=50% This will be a percentage of the engine's full force and you could assign keyboard keys to change this. float EngineForce = 4;
Update Every Frame
//Calculate engine's acceleration value EngineAcceleration = (EngineImpulse * EngineThrotle)/BallsMass; //This is a vector * a scaler divided by a scalar. I "think" XNA will handle this, but I'm not sure I've tried it. BallsPosition = BallsPosition + Gravity + EngineAcceleration;
I think that'll pretty much get you there. By controlling the "throtle" value, you should be able to control the engine. To rotate the engine, you need to rotate the EngineImpulse (or possibly the EngineAcceleration) vector. Just don't change the length of the EngineImpulse vector or you will be changing it's force/power.
Hope that helps.
#18
Re: Implementing 2D Physics
Posted 11 May 2012  07:31 PM
bonyjoe, on 11 May 2012  08:31 AM, said:
Also I'm sure you have probably figured out the terminal velocity already but just check it for > terminal velocity and < terminalvelocity, if it breaks one of these then just set it correctly to either positive or negative terminal velocity.
Daniel, BonyJoe is right. But I wanted to expand on what he said a bit. He pointed out that you keep trying to put mass into the gravity formula. I think that's because you know there's "some sort" of relationship between mass and gravity. I wanted to go ahead and expand on that idea, if you're interested.
We had a flat out number for the gravitational acceleration, but that's not "really" the actual number. That's just an average that's going to work pretty much always. So what's the actual formula?
Let F = the Force of Gravity
Let G = the Gravitational Constant which is always 6.67 * 10^11 Newton meters squared per kilogram squared.
Let Me = the Mass of the Earth 5.98*10^24 kilograms
Let Mo = the Mass of the object caught in the earth's gravitational field measured in kilograms
Let r = the distance between the two object (which is probably most easily estimated by just measuring the distance from the center of the earth to the object)
F=G(Me*Mo)/r^2
So, if you combine that with F=Mo*A and rewrite that to get acceleration, you get A=F/Mo.
Combine the formulas to get an acceleration and you get
A=F/Mo=(G(Me*Mo)/r^2)/Mo
Except that F here is the combined vector of all forces. But if we ignore that the Mo's cancel one another out.
And you wind up with A= G*Me/r^2.
In other words the object's mass doesn't matter at all compared to the earth's mass. And just think how inconsiquential any thing on earth is to the size of the entire earth. A fully loaded down aircraft carrier seems to be a lot of mass, but it's nothing compared to the size of even the smallest state in the United States, let alone the whole earth.
If you write this out for a 50,000 kg object on paper it becomes quite clear:
F= 0.000,000,000,066,7 * 5,980,000,000,000,000,000,000,000 * 50,000 / 6,378,160^2
And then you still have to divide that force by 50,000 which cancels out the 50,000, in order to get the acceleration. But it's really the earth's radius that makes the majority of the answer. It doesn't look like much compared to the earth's mass, but it's squared. So, it's actual value is 40,680,924,985,600. That may still seem small to the earth's mass, but remember the mass doesn't change as you get further and further from the earth. But the distance constantly changes and is constantly squared. So, by the time you reach the upper atmosphere you're esentially weightless.
The moon's mass is a lot more close to the earth's. And the moon's mass pulls on the earth's oceans with enough force to create the tides.
But if you want to change your formula's for other planets, you can calculate thier gravitational acceleration based on this formula and their mass.
Basically, it's going to be the Gravitational Constant times the mass of the planet divided by the distance between the planet's center squared.
This post has been edited by BBeck: 11 May 2012  07:35 PM
#19
Re: Implementing 2D Physics
Posted 11 May 2012  10:11 PM
Yes bonyjoe is right, I am probably trying to get a result without thinking about it. I read what you said, and I kind of understand it .
If your basically saying that mass is irrelevant, because it's all relative to the earth (massive). Despite being true, that's not really what I want then.
Maybe mass is not the right variable for the job. I really want something that will separate the fall speed of the objects, so a scalar.
As I said before, I can get very intricate with this, but then I might as well use an efficient engine.
Thanks for the post though BBeck, as you cleared up some questions,
Thanks again,
Daniel,
#20
Re: Implementing 2D Physics
Posted 12 May 2012  01:36 PM
DanielLeone, on 11 May 2012  10:11 PM, said:
Yes bonyjoe is right, I am probably trying to get a result without thinking about it. I read what you said, and I kind of understand it .
If your basically saying that mass is irrelevant, because it's all relative to the earth (massive). Despite being true, that's not really what I want then.
Maybe mass is not the right variable for the job. I really want something that will separate the fall speed of the objects, so a scalar.
As I said before, I can get very intricate with this, but then I might as well use an efficient engine.
Thanks for the post though BBeck, as you cleared up some questions,
Thanks again,
Daniel,
There's no reason that it has to be realistic.
But if you want to make it realistic there are only a couple of ways to control the speed at which it falls. It's falling because gravity is accelerating it every frame. So, you could reduce gravity or you can oppose it. The ways you can oppose it are either with a directly opposing force  like our rocket engine  bouyancy, or drag. We already covered the engine. Bouyancy is based on the weight of the object being lighter than the weight of the "fluid" it displaces like a hot air balloon. So that pretty much just leaves us with drag.
Right now, we've discussed drag as "terminal velocity" and just assigned it a number for it's acceleration. But it's really this formula:
Velocity = SquareRoot((2 * Mass * Gravity)/(Density * Projected Area * Drag Coefficient))
Drag and Terminal Velocity aren't covered in my physics book. I'm not sure why. Seems a bit strange that it's not covered. But anyway, that means I'm having to figure this out as we speak. I've basically been looking at it all morning and trying to figure out the relationship between Bouyancy and drag. I haven't been able to tie the two together. And it basically boils down to the fact that I don't understand why velocity is squared in the drag formula and why you divide by 2.
Anyway, I don't have much to tell me how this is done. So, I'm trying to figure it out in this post. Take everything in this post with a "grain of salt". I think it's somewhere between right and mostly right.
Bouyancy is the upward force created by displacing a given volume of fluid. It's what makes boats float and hot air balloons fly.
The force of bouyancy in Newtons is:
F=Mo * Gravity
where Mo is the mass of the displaced fluid, which is calculated as Volume * Fluid Density.
Fluid Density is calculated like so:
Density = (Absolute Pressure/(Specific Gas Constant*Absolute Temperature)
Calculating fluid density can get a little ugly because it involves pressure, temperature, and the molar mass of the fluid and so forth.
According to International Standard Atmosphere, the density of air at sea level and 15 degrees Celcius is 1.225 kg/m^3.
So, the bouyancy force is:
F=1.225 * Volume m^3 * gravity.
For a ball, it's cubic Volume is:
V=(4/3)*Pi*r^3
So a ball with a radius of 0.5 meters has a cubic volume of 0.52 m^3 (if I plugged that into the calculator right. Seems about right since a cube should have 1m^3 volume.
So the Force of the ball's bouyancy is:
F=1.225 * 0.52 * 9.81m/sec = 6.25 (Newtons I think)
So that is the upward force of bouyancy and the downward force of "weight" is Mass of Object * Gravity.
Let Mo=Mass of the object
Let G=Gravitational Acceleration
Let 1.225 = Density of air
Let Vo = Volume of the object
Let A = Acceleration of Bouyancy
Bouy=(1.225*Vo*G)(Mo*G)
A=Bouy/Mo
This would be an an upward force (unless it's negative and then it's a downward force).
Here's the formula that I'm getting for drag:
Let A=Projected Area  the area of the shadow cast if a light is shining behind the direction of movement
Let Vc=Cubic Volume of fluid displaced
If the object is not moving, this is the cubic volume of the object. If the object is moving then you take the projected area and multiply it times the distance moved during that period of time. This is the volume of the fluid being displaced during that time period of movement. Use the larger of cubic volume or volume of displaced fluid for V. So, the faster the object moves, the greater V becomes and the more drag that you have.
Let d=Fluid's Density
Let C=Drag Coefficient (http://en.wikipedia.org/wiki/Drag_coefficient)
Let v=Velocity
Drag=(C*d*v*Vc)/2
But the drag formula I found on the Internet is:
Drag=(C*d*v^2*A)/2
Terminal Velocity occurs when the Drag force is equal to the movement force.
F1=M*A. So, the movement force is Gravity Acceleration * mass.
F2=Drag
Vt occurs when F1F2=0 or when F1=F2
Let M=Mass of the object
Let G=Acceleration of gravity which is 9.81m/sec^2
Let A=Projected Area  the area of the shadow cast if a light is shining behind the direction of movement
Let d=Fluid's Density
Let C=Drag Coefficient (http://en.wikipedia.org/wiki/Drag_coefficient)
Let v=Velocity
M*G=(C*d*v^2*A)/2
Solving for v (terminal velocity), we get
1=(C*d*v^2*A)/(2*M*G)
1/(C*d*v^2*A)=1/(2*M*G)
(C*d*v^2*A)/(C*d*v^2*A)=(C*d*v^2*A)/(2*M*G)
1=(C*d*v^2*A)/(2*M*G)
1*(2*M*G)=(C*d*v^2*A)*(2*M*G)/(2*M*G)
2*M*G=C*d*v^2*A
2*M*G=C*d*v^2*A
(2*M*G)/(C*d*A)=v^2
v^2=(2*M*G)/(C*d*A)
v = SqrRoot((2*M*G)/(C*d*A))
Wow, more algebra than I've done in a year.
You can get the drag formula here which is pretty much the same formula I just went through.
http://www.grc.nasa....lane/termv.html
So, bottom line is that you would check your velocity every frame and not let it pass this terminal velocity
In code, terminal velocity would look something like this:
Vector2 TerminalVelocity = new Vector2.Zero; Vector2 ObjectsVelocity; float ObjectsMass; //Probably in kilograms. You have to use the same units to get the math to work out right and so stick with SI units. float Gravity = 9.81/FramesPerSecond; //We've been doing this as a vector, but it's always pointing in the same direction and a float's probably good for this. float CoefficientOfDrag = 0.47; //http://en.wikipedia.org/wiki/Drag_coefficient float AirDensity = 1.225; //http://en.wikipedia.org/wiki/Density_of_air float ProjectedArea = Pi*Radius^2; //Area of a circle TerminalVelocity = SqrRoot((2*ObjectsMass*Gravity)/(CoefficientOfDrag*AirDensity*ProjectedArea)); if(ObjectsVelocity.y.AbsoluteValue>TerminalVelocity) { ObjectsVelocity.y = TerminalVelocity; //Terminal V should always be downward. }
So, to kind of sum it all up as to how to control the various objects' fall speed: your only choice in a realistic simulation is to control the opposing force. In a vaccume they are all going to fall at the exact same rate, no matter their size, mass, or anything else. You can either oppose their fall with a force like a rocket engine, or you can oppose it through bouyancy or drag. Both bouyancy and drag take mass into consideration.
For drag, also known as terminal velocity, it will be controlled by gravity of the planet, the object's mass, the drag coefficient, the air density, and the object's projected area. All, of those will affect the rate of maximum fall. To get the object to fall slowly, you would probably do something like greatly increase its projected area while greatly decreasing it's mass. You may have to go a bit extreme with the mass, like 0.00000000000001f. Remember that it needs to be as light as a helium balloon to fall to the ground slowly, or it needs to have the projected area of a parachute and maybe a drag coefficient that's through the roof like 3.0f to fall like it's attached to a parachute.
I'm tempted to try and workout a "general" drag formula that includes bouyancy, but I think it's beyond my abilities or reference material anyway.
Vt occurs when Force of Acceleration = Drag, F1F2=0 or when F1=F2
Let M=Mass of the object
Let a=Acceleration of gravity which is 9.81m/sec^2
Let P=Projected Area  the area of the shadow cast if a light is shining behind the direction of movement
Let d=Fluid's Density
Let C=Drag Coefficient (http://en.wikipedia.org/wiki/Drag_coefficient)
Let v=Velocity
Let Vc=Cubic Volume of fluid displaced
If the object is not moving, this is the cubic volume of the object. If the object is moving then you take the projected area and multiply it times the distance moved during that period of time. This is the volume of the fluid being displaced during that time period of movement. Use the larger of cubic volume or volume of displaced fluid for V. So, the faster the object moves, the greater V becomes and the more drag that you have.
M*a=(C*d*v*Vc*P)/2
M*a.length((C*d*v*Vc*P)/2) = Resulting Vector
Vector2 TerminalVelocity = new Vector2.Zero; Vector2 ObjectsVelocity; float ObjectsMass; //Probably in kilograms. You have to use the same units to get the math to work out right and so stick with SI units. float Gravity = 9.81/FramesPerSecond; //We've been doing this as a vector, but it's always pointing in the same direction and a float's probably good for this. float CoefficientOfDrag = 0.47; //http://en.wikipedia.org/wiki/Drag_coefficient float AirDensity = 1.225; //http://en.wikipedia.org/wiki/Density_of_air float ProjectedArea = (Pi*Radius)^2; //Area of a circle Vector2 DragVector =new Vector2.Zero; float Distance = 0.0f; //Distance traveled through in a frame Distance = Velocity.Length; VolumeDisplaced = ProjectedArea*Distance; if(VolumeDisplaced<ObjectVolume) { VolumeDisplaced = ObjectVolume) } AirDensity = 1.225 * AltitudeMultiplier; //Changing the air density for altitude should affect the bouyancy and keep it from floating off into space. But I haven't thought this completly through. Drag =(CoefficientOfDrag*AirDensity*Velocity.Length*VolumeDisplaced)/(2*ObjectsMass); //Drag is always going to be facing exactly opposite the Velocity. DragVector = Velocity.Normalize; //Normalized to make the velocity's length unimportant (we only want direction). DragVector *= 1; //Reverse the direction of the vector to make it oppose velocity. DragVector *= Drag; //Make the DragVector's magnitude equal to the force of drag. Velocity += Drag; //Combine the two vectors together to have the velocity affected by drag. Velocity += Acceleration; //Don't forget to add in an acceleration vector which is the gravity acceleration vector + rocket engine acceleration.
Really, I don't know if this last set of code will work "right". That's what I'm thinking the code might look like for an all inclusive drag formula. If it works right, then a bouyant object, like a balloon can actually float and this code will also determine the object's maximum speed.
Anyway, I would suggest playing around with that first block of code I posted. If that works, you may want to play around with the second block and see if it works.
This post has been edited by BBeck: 13 May 2012  06:35 AM
#21
Re: Implementing 2D Physics
Posted 12 May 2012  02:32 PM
Vector2 Velocity; //Per frame. Vector2 Acceleration; //Gravity or whatever done per frame Vector2 EngineAcceleration; //Also per frame and maybe multiplied by a throtle percentage float TerminalVelocity = 56.0f/FramesPerSecond; //Meters per second. Roughly speed of a skydiver falling. Set to what you want max move speed to be. Velocity += Acceleration + EngineAcceleration; //Check terminal velocity after accelerations have been added. if (Velocity.Length>TerminalVelocity) { //Normilizing the velocity vector removes the velocity //amount (sets it to one) while preserving the direction. //Multiplying by TerminalVelocity sets the velocity //amount to the amount of Terminal Velocity because it's //a normalized vector. Velocity = Velocity.Normalize * TerminalVelocity; }
The key thing to remember here is that every object will have it's own personal terminal velocity.
Remember that terminal velocity includes mass (the momentum pushing on the air column), the aerodynamics (Coefficient of drag), and size of the column of air being displaced (velocity times projected area). So, any of those things can cause the terminal velocity to change. And if you're going to sum it all up in one number, then you should probably consider that all those things go into that number.
A feather is going to have a very low terminal velocity, because it has low mass pushing against the air column, and it has a relatively high projected area not to mention that it's drag coefficient is through the roof.
A rock is going to fall faster because it has more mass pushing against the air column (compared to it's projected area), and it probably has a little better drag coefficient.
And it's the point where the air resistance is equal to the acceleration where Terminal Velocity occurs. So, no more acceleration can occur at that point.
Another thing to keep in mind is scale. If you're object is falling 0.5 meters per second, and your screen is 0.25 meters tall, then the object will hit the bottom of the screen in less than half a second even though it's really falling super slow.
If a pixel is 1 meter, then 53 m/second is 53 pixels per second.
Just don't forget that your scale can make things look like they are falling a lot faster or a lot slower than they really are.
If your screen shows 10 kilometers of elevation, that's 10,000 meters and falling 53 m/second is pretty darn slow, even though you're falling half a football field every second. Likewise, if your screen shows 1 meter of elevation, then 53 m/second is going to be 1/53rd of a single second (or so fast you probalby won't see it move).
This post has been edited by BBeck: 12 May 2012  02:42 PM
#22
Re: Implementing 2D Physics
Posted 12 May 2012  02:57 PM
DanielLeone, on 11 May 2012  10:11 PM, said:
If your basically saying that mass is irrelevant, because it's all relative to the earth (massive). Despite being true, that's not really what I want then.
Mass of the falling object is irrelevant when falling in a vaccume. But it is very relevant when falling through a fluid, like air, because of the drag(wind resistance). You're pushing an air column out of the way to do the traveling and that air column has weight. So the weight you apply against it is a significant factor in determining where the balancing point is.
So, basiclly, mass is not going to be involved in velocity or gravitational acceleration. But it will be involved in determing terminal(maximum) velocity because it's part of the force that fighting the force of wind resistance.
We all know dropping a piece of paper and a rock that the rock will hit the ground first. It's not because of gravity. It's because of the paper's Coefficient of Drag, low mass, and high projected surface area. In other words, it has to push a lot of air out of the way in order to fall flat and that's huge compared to it's mass. But you'll also notice the paper will "fall like a rock" if you turn it to face horizontally instead of vertically. That paper thin edge will have almost no Drag compared to the mass of the paper. Of course, getting it to fall perfectly that way is more than a little difficult because it trys to turn itself facing vertically again.
#23
Re: Implementing 2D Physics
Posted 12 May 2012  06:34 PM
Give me a while to read all this
Thanks,
Daniel,
#24
Re: Implementing 2D Physics
Posted 13 May 2012  05:20 AM
#25
Re: Implementing 2D Physics
Posted 13 May 2012  05:56 AM
bonyjoe, on 13 May 2012  05:20 AM, said:
Daniel, Yep. Writing books is pretty much what I do. ;) It's kind of "stream of concious" writing, where I'm kind of thinking it through as I write it. So, it probably helps to read the posts backwards, since my thoughts become more "coherent" as I get towards the end.
Bonyjoe, thanks. I know I've been impressed with a lot of your posts.
Some of it's from memory. Most of the formulas I either have to look up in the text book or google. It's kind of like programming; I know basically what needs to be done and how to do it, but I'm constantly looking back at the books for examples and specifics.
I guess I'm a very curious person. A big part of my personality is "needing" to know how everything in the universe works. It's both a help and a hinderance at times. Often, it's like I have to become an "expert" at something before I can begin to do it.
Anyway, I've ended up with a very broad education. And a lot of it, I took the time to really "understand it" rather than just doing what I needed to do to pass the tests. I took Biology 101 a few years back and I went WAY beyond what the teachers wanted even to the point where I was seeing the mistakes the teachers were making. For example, we had this one test question that was really a Chemistry question related to biology and I knew it was wrong because I had actually been researching and reading other books beyond just the text book so that I would actually "know" how it worked rather than just memorizing what the textbook said. I ended up bringing in documentation and proving that the test question was wrong.
But with gaming, I think having a broad range of knowledge is a big part of what I have to offer to help people with. I'm not the best programmer in the world; I only do a little programming here and there professionally. I'm not the best musician in the world. I'm not the best modeler or texture painter. I'm not the best at lighting or sound effects. I'm not the best animator. And I don't know Calculus so there's some serious limits to what I can do with math and physics. But, I know  at least at a beginner level  how to do all of it. And I think that's kind of rare. So, I hope to "bring that to the table" and help people who are just getting started out with it.
And I really like physics. :) I guess that's because it explains how the universe works and it kind of facinates me. I actually thought that maybe I should have become a physicist and even considered going back to school for a physics degree. It really fits my personality. I guess I decided not to because my career as a Database Administrator really started taking off and it would have been a huge life change and pay drop to start over, not to mention it would probably have to mostly be funded out of my own pocket.
Anyway, hope my ramblings prove useful to people. :)
This post has been edited by BBeck: 13 May 2012  06:20 AM
#26
Re: Implementing 2D Physics
Posted 13 May 2012  07:04 AM
DanielLeone, on 12 May 2012  06:34 PM, said:
Give me a while to read all this
Thanks,
Daniel,
I love your animation by the way. Awesome! I've never quite gotten "there", but I've abused a few keyboards before and even threw a chair across the room once after working for an entire day and not being able to find the bug in my program. :) Nothings more frustrating then not being able to find the bug in your code that's right in front of your face.
#27
Re: Implementing 2D Physics
Posted 16 May 2012  06:56 AM
Anyway, they also go into vectors in their Physics section (you almost have to for any complete discussion of physics) and there they immediately get into the subject and probably make it more approachable. And that reminded me of this thread.
I wanted to point out that there's a lot of info on Physics (and other stuff like Matrices that's probably good for game programmers) at Khan Academy for free.
http://www.khanacademy.org/#physics
They've got a really good explination of the brick and feather problem that's even better than how I explained it.
http://www.khanacade...herfallfaster
This post has been edited by BBeck: 16 May 2012  07:14 AM
#28
Re: Implementing 2D Physics
Posted 17 May 2012  05:34 AM
It made mostly a lot of sense to me, and I realised that what I want in simple terms, is mass, acceleration, and maybe some changeable value for air resistance (or maybe humidity).
Probably the wrong terms, but I don't really know what else to call them, so I'll use that for now.
When I see this picture, I understand what it does, but really don't see a point to it (as of yet) seen as my game isn't really going to be based fundamentally on physics.
The force on a particular objects basically equals gravity * ((mass of object * mass of planet(or something)) / distance between the two).
In a physics engine this maybe all taken into account, but in any game, I don't really think it matters too much, because you don't often relate to the planet, surface your on. The same would go in the case of the mass of the planet,
therefore I think it's completely reasonable to give this an arbitrary value.
Going with that, the new equation,
Force = (Gravity * mass).
That covers Force then you get Acceleration. Calculated with
Acceleration = (Force / mass).
So not entirely sure but in terms of code, I presume it would look something like this:
force += Vector2.Multiply(gravity, mass); acceleration = Vector2.Divide(force, mass); position += acceleration;
Now my objects behave as expected, they fall at the same speed. I am sure this is because Mass is multiplied, and then divided, making it irrelevant.
So, I can remove the mass in say acceleration, which would make that irelavent aswell because it would equal force. So then I could just redo the code like this:
force += Vector2.Multiply(gravity, mass); position += force;
That would probably make all of this work a waste of time, because it doesn't really follow the rules at all.
Now, that is not a problem unless there is some reason that people strongly suggest.
The alternative is to include a nonarbitrary value for air resistance, or make it personal foreach Object.
This is all getting very confusing , and a bit overwhelming.
Do you think I should be trying to include all of these, or stick with my last code example?
edit : That last part probably sounded a bit brief because I wrote much more before it got way to confusing, even writing it all down, so I removed most of it. Basically I asking do you think I should take this further and include many more factors, or just use my last code example?
Thanks in advance,
and for all the great advice you've supplied,
Daniel,
This post has been edited by DanielLeone: 17 May 2012  05:37 AM
#29
Re: Implementing 2D Physics
Posted 17 May 2012  12:27 PM
There are several things that are important to keep straight. First, they are giving Newton's Law of Universal Gravitation. They include G for gravity, but that's not gravity the way we've been discussing it. We've been talking about gravitational acceleration. Big G is the gravitational constant which is 6.674×10−11 N m2 kg−2 and never ever changes anywhere in the universe. Little g is the acceleration caused by the gravity of a planet and that is 9.81m/sec^2 for earth. Be careful not to get the two confused. Little g in their equations is a in the F=m*a equation. So Little g = ((Big G * Mass of the Planet)/(Distance of object from the center of the planet)^2). And that answer can be plugged into the formula F=g * m (F=a*m), which is Force = gravitational acceleration * mass of the object.
The next thing that I wanted to point out is that Force is a measure of energy used to move an object (assuming that we can call the force of gravity a form of energy). On a rocket it might be the part of the energy of the rocket fuel exploding that transfers to movement (part of it will transfer to heat and light). Force isn't how much the object is caused to move, but rather how much energy was spent trying to make it move. Force is how hard you push, and acceleration is how much faster or slower that push makes it go. That's why a=F/m. In other words, a is the output and F is the input. F is how much energy was spent trying to push the object, but the "heavier" (more massive) the object, the less impressive the end result (the less the acceleration). Acceleration is a change to the velocity, because velocity will never ever ever change without an acceleration changing it.
I believe what they are saying in the brick and feather story, is that the Force(F) of earth's gravity field increases on more massive objects, thereby canceling out the fact that the object is more massive and requires more force to move. So, in the end, a is always about 9.81m/sec^2 for all objects on earth no matter how massive (although altitude will change this).
The only time you are going to use the F=(G*m1*m2/r^2) formula is when you want to calculate the difference in gravity as you go from orbit to landing on the planet, or you're trying to figure out the gravitational acceleration on a nonearth planet. Other than that, you can pretty much forget it.
The only time you need to worry about F is when applying a force from something other than gravity. For gravity, you already know that a =9.81m/sec^2 (unless you want to go back to the Universal formula and calculate it for another planet or at higher altitudes). But if the force is coming from a rocket engine, or another object colliding with the object, then you probably need to know how much force is applied against the object's mass to determine how much it accelerates the object.
Also, if you haven't taken a physics class you may not know Newton's first law of motion  "An object that is at rest will stay at rest until something acts on it, but a body in motion will continue that exact same motion forever and ever unless something acts on it." On earth, we're so used to living in earth's gravitational field (which always constantly accelerates everything around us (things stay on the ground because gravity is constantly trying to suck them to the core of the planet). Drag and wind resistance also affect everything we see every day. So, it's hard for us to imagine what life is like outside of this gravity and air resistance.
But I mention Newton's first law because it means you are going to have a velocity vector and that will cause the object to move forever in that direction until something (like gravity or drag) cause it to change.
Any time you are applying a force, you probably want to just make up that number for the amount of force, but keep it measured in Newtons. It's just the energy going into trying to make it move, whether it moves or not.
So, you are almost never going to want to calculate the force... that I can think of off the top of my head. If you want to calculate acceleration, you will decide the force applied, and divide that by the mass of the object. But for gravity your answer for acceleration is always 9.81m/sec^2.
http://en.wikipedia...._laws_of_motion
So, to recap, position is where the object is at. Velocity is how much the position changes in a second or a frame. Acceleration is how you change the velocity; without some sort of acceleration (positive or negative) the velocity will remain the same until something blocks the object's path preventing it from moving any further in that direction. Force is applied to an object, which means dividing the force by the mass of the object, to give you an amount of acceleration. If the object is moving through air it will have a terminal velocity due to the air. The terminal velocity is the maximum velocity with that amount of acceleration being added forever and ever. (If the acceleration changes terminal velocity can change, but that's not going to happen with the force of gravity.)
I would probably code it as follows:
//Play with EngineForce, ObjectMass, Throtle, and maybe Terminal Velocity //because I'm largely just throwing out made up numbers for force and mass // and I'm not sure if they will look good on your screen. Vector2 Position; //Coordinate stored as a vector(the other vectors are ACTUAL vectors, not so much with this one) Vector2 Velocity; //Per frame. Vector2 Gravity = new Vector2(0f, 9.81f/FPS, 0f); //Gravity per frame //EngineAcceleration is a direction without a value here. Vector2 EngineAcceleration = new Vector2(0f,1f,0f); //Upward thrust Normalized float EngineForce = 3f; //Measured in Newtons float Throtle = 1.0f; //100% throtle float ObjectsMass = 5f; //Mass in kilograms. float ObjectsTerminalVelocity = 56.0f/FramesPerSecond; //Meters per second. Roughly speed of a skydiver falling. Set to what you want max move speed to be. //EngineAcceleration is "assigned" an amount here //Force is a scalar here which increases the length of the Acceleration vector. EngineAcceleration = EngineAcceleration * (EngineForce*Throtle/ObjectsMass); Velocity += Gravity + EngineAcceleration; //Check terminal velocity after accelerations have been added. if (Velocity.Length>ObjectsTerminalVelocity) { //Normilizing the velocity vector removes the velocity //amount (sets it to one) while preserving the direction. //Multiplying by TerminalVelocity sets the velocity //amount to the amount of Terminal Velocity because it's //a normalized vector. Velocity = Velocity.Normalize * ObjectsTerminalVelocity; } Position += Velocity;
This post has been edited by BBeck: 17 May 2012  12:57 PM
#30
Re: Implementing 2D Physics
Posted 18 May 2012  04:47 AM
BBeck, on 18 May 2012  03:27 AM, said:
So, to recap, position is where the object is at. Velocity is how much the position changes in a second or a frame. Acceleration is how you change the velocity; without some sort of acceleration (positive or negative) the velocity will remain the same until something blocks the object's path preventing it from moving any further in that direction. Force is applied to an object, which means dividing the force by the mass of the object, to give you an amount of acceleration. If the object is moving through air it will have a terminal velocity due to the air. The terminal velocity is the maximum velocity with that amount of acceleration being added forever and ever. (If the acceleration changes terminal velocity can change, but that's not going to happen with the force of gravity.)
acceleration *= (force / mass); velocity += (gravity + acceleration); position += velocity;
Okay, I read what you've said, and want to say thanks for clarifying so many things. That last part really helped.
Now I think that I understand what all the values do, and when to use them.
So I used what you provided and got this code (above). Now I played around with it a bit, and it doesn't really work .
Basically acceleration starts at zero. So when acceleration *= x, it still going to equal Zero. Therefore, it's just increment position by gravity.
This obviously needs to change, but it seems wrong to me to give the variables an initial value.
So that is the first issue.
Then I have the bouncing, probably fixed with the previous issue, but I just wanted some advice.
Basically the bounce method negates 'a' value. I wanted to know which value this should be, because although BBeck, you said that velocity should never(not often) be directly changed , it seems like the one for me? This could be (is probably) wrong, but they all seem like they could fit, (acceleration, velocity, force).
This was my 'bounce' method for reference:
if (IntersectEdge(ScreenManager.Room, out x)) { if (x) { velocity = new Vector2(velocity.X * elasticity, velocity.Y * elasticity); } if (!x) { velocity = new Vector2(velocity.X * elasticity, velocity.Y * elasticity); } }
Don't worry about the x and stuff, just the main 2 lines. That basically as I said Negate a value.
At the moment this works, except acceleration isn't really taken into account, well it is, just it hasn't got a value (0).
As always,
Thanks in advance,
Daniel,
The help and time you give is greatly appreciated.
