Jump to content
  • Advertisement
Sign in to follow this  
Psychopathetica

Falling Physics

This topic is 2106 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there. I have a question on 2D falling physics. I've correctly implemented a simple program that has a simple circle falling down until it hits the ground with gravity being 9.80665 (earth gravity), 10 being my mass, 1/60 being my timestep, and any integrator of my choosing:

 

[source]

Private Sub Integrate(Obj As PHYSICS2D, dt As Single, Integrator As CONST_INTEGRATOR)

    Dim Old_Position As Vector2D
    Dim Old_Velocity As Vector2D
    Dim Old_Acceleration As Vector2D
    
    Dim k1 As Vector2D, k2 As Vector2D, k3 As Vector2D, k4 As Vector2D
    Dim l1 As Vector2D, l2 As Vector2D, l3 As Vector2D, l4 As Vector2D
    
    
    With Obj
        .Acceleration.X = .Force.X * .One_Over_Mass
        .Acceleration.Y = .Force.Y * .One_Over_Mass
        
        Select Case Integrator
        
            Case FORWARD_EULER
                .Position.X = .Position.X + .Velocity.X * dt
                .Position.Y = .Position.Y + .Velocity.Y * dt
                
                .Velocity.X = .Velocity.X + .Acceleration.X * dt
                .Velocity.Y = .Velocity.Y + .Acceleration.Y * dt
            Case SECOND_ORDER_EULER
                .Position.X = .Position.X + .Velocity.X * dt + 0.5 * .Acceleration.X * dt * dt
                .Position.Y = .Position.Y + .Velocity.Y * dt + 0.5 * .Acceleration.Y * dt * dt
                
                .Velocity.X = .Velocity.X + .Acceleration.X * dt
                .Velocity.Y = .Velocity.Y + .Acceleration.Y * dt
            Case VERLET
                Old_Position.X = .Position.X
                Old_Position.Y = .Position.Y
                
                .Position.X = .Position.X + .Velocity.X
                .Position.Y = .Position.Y + .Velocity.Y
                
                .Velocity.X = .Position.X - Old_Position.X + .Acceleration.X * dt * dt
                .Velocity.Y = .Position.Y - Old_Position.Y + .Acceleration.Y * dt * dt
            Case VELOCITY_VERLET
                Old_Acceleration.X = .Acceleration.X
                Old_Acceleration.Y = .Acceleration.Y
                
                .Position.X = .Position.X + .Velocity.X * dt + 0.5 * Old_Acceleration.X * dt * dt
                .Position.Y = .Position.Y + .Velocity.Y * dt + 0.5 * Old_Acceleration.Y * dt * dt
                
                .Velocity.X = .Velocity.X + 0.5 * (Old_Acceleration.X + .Acceleration.X) * dt
                .Velocity.Y = .Velocity.Y + 0.5 * (Old_Acceleration.Y + .Acceleration.Y) * dt
            Case SECOND_ORDER_RUNGE_KUTTA
                k1.X = dt * .Velocity.X
                k1.Y = dt * .Velocity.Y
                l1.X = dt * .Acceleration.X
                l1.Y = dt * .Acceleration.Y
                
                k2.X = dt * (.Velocity.X + k1.X / 2)
                k2.Y = dt * (.Velocity.Y + k1.Y / 2)
                l2.X = dt * .Acceleration.X
                l2.Y = dt * .Acceleration.Y

                .Position.X = .Position.X + k2.X
                .Position.Y = .Position.Y + k2.Y
                .Velocity.X = .Velocity.X + l2.X
                .Velocity.Y = .Velocity.Y + l2.Y
            Case THIRD_ORDER_RUNGE_KUTTA
                k1.X = dt * .Velocity.X
                k1.Y = dt * .Velocity.Y
                l1.X = dt * .Acceleration.X
                l1.Y = dt * .Acceleration.Y
                
                k2.X = dt * (.Velocity.X + k1.X / 2)
                k2.Y = dt * (.Velocity.Y + k1.Y / 2)
                l2.X = dt * .Acceleration.X
                l2.Y = dt * .Acceleration.Y
                
                k3.X = dt * (.Velocity.X - k1.X + 2 * k2.X)
                k3.Y = dt * (.Velocity.Y - k1.Y + 2 * k2.Y)
                l3.X = dt * .Acceleration.X
                l3.Y = dt * .Acceleration.Y
                
                .Position.X = .Position.X + k1.X * 1 / 6 + k2.X * 2 / 3 + k3.X * 1 / 6
                .Position.Y = .Position.Y + k1.Y * 1 / 6 + k2.Y * 2 / 3 + k3.Y * 1 / 6
                .Velocity.X = .Velocity.X + l1.X * 1 / 6 + l2.X * 2 / 3 + l3.X * 1 / 6
                .Velocity.Y = .Velocity.Y + l1.Y * 1 / 6 + l2.Y * 2 / 3 + l3.Y * 1 / 6
            Case FORTH_ORDER_RUNGE_KUTTA
                k1.X = dt * .Velocity.X
                k1.Y = dt * .Velocity.Y
                l1.X = dt * .Acceleration.X
                l1.Y = dt * .Acceleration.Y
                
                k2.X = dt * (.Velocity.X + k1.X / 2)
                k2.Y = dt * (.Velocity.Y + k1.Y / 2)
                l2.X = dt * .Acceleration.X
                l2.Y = dt * .Acceleration.Y
                
                k3.X = dt * (.Velocity.X + k2.X / 2)
                k3.Y = dt * (.Velocity.Y + k2.Y / 2)
                l3.X = dt * .Acceleration.X
                l3.Y = dt * .Acceleration.Y
                
                k4.X = dt * (.Velocity.X + k3.X)
                k4.Y = dt * (.Velocity.Y + k3.Y)
                l4.X = dt * .Acceleration.X
                l4.Y = dt * .Acceleration.Y
                
                .Position.X = .Position.X + k1.X / 6 + k2.X / 3 + k3.X / 3 + k4.X / 6
                .Position.Y = .Position.Y + k1.Y / 6 + k2.Y / 3 + k3.Y / 3 + k4.Y / 6
                .Velocity.X = .Velocity.X + l1.X / 6 + l2.X / 3 + l3.X / 3 + l4.X / 6
                .Velocity.Y = .Velocity.Y + l1.Y / 6 + l2.Y / 3 + l3.Y / 3 + l4.Y / 6
        End Select
    End With

End Sub

[/source]

 

And in my game loop to update the physics I do this:

 

[source]
        Delta_Time = Get_Elapsed_Time_Per_Frame
        If Delta_Time > 0.25 Then Delta_Time = 0.25
        Accumulator = Accumulator + Delta_Time
        
        While (Accumulator >= Time_Step)
            Accumulator = Accumulator - Time_Step
            Integrate Obj, Time_Step, VERLET
            Time = Time + Time_Step
        Wend
        
        Check_Collision Obj
        Render

[/source]

 

The problem is that it appears to fall too slow and slowely has the circle falling faster and faster till it hits the ground. Should i apply a scale factor on all my updated position to accommodate this issue (which pretty much does fix the problem only I never see anyone do this nor do I think it is right) ? How do the professionals do it or what is the correct way to make it seem more real? The way it visually looks like its falling is as though if the camera is very far away from a skydiver and you slowely see him fall down. Only I wanna make it fall like you are right there and it falls like you drop something. I dont wanna guess at the solution. I wanna do it as to whatever is the correct method. Thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement

You have left out some details in the OP, so the following are hints of what may go wrong:

 

1. Do you use the correct units? The gravity constant is given in m/s^2 (derived from the magnitude), so do you further use SI units, too?

 

2. How do you use the gravity constant g? From the code I assume you should compute a gravity force as G = ( 0, -1 * m * g ), and sum it up vector-wise with perhaps other forces, normally in each time step. Is it done so? Have you printed out Obj.Acceleration for verification purposes if nothing but gravity happens, and does it show up as (0, -g)?

 

3. Do you consider a scale when rendering?

Share this post


Link to post
Share on other sites

Gravity is just the force I applied:

 

A = G / M

 

or

 

A = G * 1 / M

 

 

But the thing is, should I scale it so it doesn't look like a skydiver from far away? Thats the point of the question cause I see noone else doing it :P

Share this post


Link to post
Share on other sites

Gravity is just the force I applied:
 
A = G / M

I'm delving deeper in what I meant:

 

In the OP you write "gravity being 9.80665". The term "gravity" is used for the phenomenon. The capital letter G is often used for the force due to gravity. The lower letter g is often used for the standard acceleration due to the gravity force on earth, i.e. the acceleration that 1 kg of mass is seeing. The (mean) magnitude of g is 9.80665, and its unit is

   [g] = m / s^2

(i.e. those of an acceleration); opposed to that, the (kanonical) unit of gravity force is

   [G] = kg * m / s^2.

 

As a formula, the gravity force on earth and its standard acceleration are connected so

   G := m * g

accordingly to the general application of force

   F := m * a

 

So, if you use the magnitude of 9.80665 for G, then your simulation is done with an acceleration of

   a = G / m = 9.80665 kg*m/s^2 / 10 kg = 0.980665 m/s^2

 

On the other hand, if you use the magnitude of 9.80665 for g (as it should be), then your simulation is done with an acceleration of

   G = 10 kg * 9.80665 kg*m/s^2 = 98.0665 kg*m/s^2

   a = G / m = 98.0665 kg*m/s^2 / 10 kg = 9.80665 m/s^2

 
In the first case you see a tenth of the acceleration you have to expect for 10 kg of mass! (BTW: This points at an important principle: Dimensional analysis.)
 
In summary: The citations "gravity being 9.80665 (earth gravity)" and "Gravity is just the force I applied" don't suit well and so were the reasoning of my question.
Edited by haegarr

Share this post


Link to post
Share on other sites

 I'm sorry I haven't been clear. I already did my gravitational force as mass * gravity. I just didnt show it. Matter of fact I havent even shown 90% of my program lol:

 

[source]

Private Function Calculate_Gravitational_Force(m As Single, g As Single) As Single
    Calculate_Gravitational_Force = m * g
End Function

[/source]

 

And when I apply the force into my acceleration, I use this function. Anyways maybe I shouldnt have shown all that stuff at all because that wasnt the point I was trying to get across. All I wanna know is if it is ok for me to use a scale factor. Because I never see anyone use it. Its falling too slow like a skydiver unless I multiply my Positions X and Y by a scale factor after integrating. For example, although its optional to use in my program cause I have a number of integrators to choose from, lets say Forward Euler for simplicity sake:

 

[source]

With Obj

 

.Velocity.X = .Velocity.X + .Acceleration.X * dt
.Velocity.Y = .Velocity.Y + .Acceleration.Y * dt
                
.Position.X = .Position.X + (.Velocity.X * dt) * .Scalar
.Position.Y = .Position.Y + (.Velocity.Y * dt) * .Scalar

 

End With

[/source]

 

If you noticed I multiplied the result by a scalar over where the positions are, using a scale value like 100. This makes it more realistic like its falling off a table, rather than falling at a tremendously slow rate like you are far away watching a sky diver fall. My question is, is this ok to do? Is it a correct method?

Edited by Psychopathetica

Share this post


Link to post
Share on other sites


... All I wanna know is if it is ok for me to use a scale factor. ...

Yes, I know, but I wanted to verify that the calculations itself are correct; better to cure the cause rather than the symptom ...

 

You write that the circle falls too slow. What falling height do you use until the ground is hit?

 

Let's say you render a 10 m high tower, and simulate the falling of a body from its top to its foot. If your simulation code is correct, then the hit occurs after approx. 1.428 seconds (neglecting any friction loss). As an observer we are used to assess physical magnitudes due to comparison. If you see the tower beneath the falling body, does the falling speed still looks to be odd?

 

In fact, it's your simulation code. You can, of course, do what you want until you claim to be physically correct. However, IMHO you should avoid to be trapped by an impression due to lack of visual context in which you observe the effect.

Share this post


Link to post
Share on other sites

With a simple free fall without air resistance and without collisions with other objects you didn't have to consider the mass [kg] at all. What matters is only the acceleration a = (0, -g, 0).

 

But to your main question - if you would have to apply a scaling factor in order to make the fall appear realistic, then you most probably have a problem with the size of your scene, as haegarr already mentioned.

Because all objects fall with the same acceleration and the total time of the fall depends only on the initial height (*), we are used to this behaviour and we can easily guess how long the falling distance is.

In older movies where special effects were done with small-scale models and not with computer animation, they were using faster cameras with more FPS to capture the action and then it is played slower. Because a wall piece from the top of a dam 50 meters tall will fall for approx. 3.2 seconds and this long time is what makes us belive that it is a huge rock falling from a huge height. But in a 1:100 model, from 0.5 meters, it will fall for 0,32 seconds and EVERYBODY would immediately notice that it's just a small model. So you have to play the footage 10times slower.

 

But in your case you don't have to scale TIME, you can simply make sure that your DIMENSIONS are correct.

 

(*) Air resistance + the shape of the object play a role, too. Sometimes very huge (a falling feather versus a falling steel ball), but usually quite insignificant, because the effects tends to be very similar for all objects.

Edited by Tom KQT

Share this post


Link to post
Share on other sites

Mass is an arbitrary factor in "falling physics". Everything falls at the same rate (generally). I didn't look over your code but I can only assume that you are creating the velocity of the object based off of a factor dependent on Mass. Remove mass, they should all fall equally.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!