Force Bug

Last time we ran into a bug where forces were not having the expected effect, today we’ll look into solving that.

To start off with, we have two vec2 objects: wind and gravity. Wind has a value of 5,0 and gravity has a value of 0,1. We want a sum of the force vectors and we create this sum with the applyForce() function, applying each force should be aggregating it into the target objects acceleration so let’s break that down step by step to see where the bug is.

applyForce(wind) is being called from the event handler and gravity is being called from the bottom of the main loop, right before the update() function, if we comment out gravity and leave just wind, we see that clicking creates the wind effect we were expecting, if we add gravity back in, we see that the wind force is nullified and the gravity force takes over.

If we move gravity to be applied when the mouse is pressed as well as the wind, it works as intended, the forces are aggregated and the motion is the sum of the two vectors, if we separate the forces and apply gravity when space is pressed, it works as expected, but if we hold the button down to constantly apply the force we see that the ball stops moving sideways and starts moving downward only, so the issue seems to be the frequency with which the gravity is being applied. Since the wind force is being applied only in the instance of the click, it doesn’t seem to have any lasting effect, let’s move it to be bound to space and allow gravity to be constant again.

This effect is closer to what we want, but it’s still not quite right, so we’ll add a few lines to output the X and Y velocity of the ball to the console to see what we get as we change the vectors. Everything seems good until we get close to 10, when the limit function comes into play it starts to mess with the other velocity component, if we comment out the limit function we see that the code performs the way that we wanted it to. Bug found!

Let’s look at the steps involved in Limit():

[pastacode lang=”cpp” manual=”void%20vec2%3A%3Alimit(float%20limit)%0A%7B%0A%20%20%20%20if%20(this-%3EgetMag()%20%3E%20limit)%0A%20%20%20%20%20%20%20%20this-%3EsetMag(limit)%3B%0A%7D%0A%0A%0A%0AgetMag()%20%7Breturn%20sqrt(%20(x*x)%20%2B%20(y*y)%20)%3B%7D%3B%0A%0A%0A%0Avoid%20vec2%3A%3AsetMag(float%20mag)%0A%7B%0A%20%20%20%20if(this-%3EgetMag()%20!%3D%200)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20this-%3Enormalize()%3B%0A%20%20%20%20%20%20%20%20this-%3Emult(mag)%3B%0A%20%20%20%20%7D%0A%20%20%20%20else%20if(%20mag%20%3E%200%20)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20this-%3Ex%20%3D%201%20*%20mag%3B%0A%20%20%20%20%20%20%20%20this-%3Ey%20%3D%201%20*%20mag%3B%0A%20%20%20%20%7D%0A%7D%0A%0A%0A%0Avoid%20vec2%3A%3Anormalize()%0A%7B%0A%20%20%20%20float%20mag%20%3D%20this-%3EgetMag()%3B%0A%20%20%20%20if%20(mag)%0A%20%20%20%20%20%20%20%20div(mag)%3B%0A%7D%0A%0A%0A%0Avoid%20vec2%3A%3Amult(float%20scaler)%0A%7B%0A%20%20%20%20this-%3Ex%20*%3D%20scaler%3B%0A%20%20%20%20this-%3Ey%20*%3D%20scaler%3B%0A%7D%0A%0A%0A%0Avoid%20vec2%3A%3Adiv(float%20div)%0A%7B%0A%20%20%20%20if%20(div%20!%3D%200)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20this-%3Ex%20%2F%3D%20div%3B%0A%20%20%20%20%20%20%20%20this-%3Ey%20%2F%3D%20div%3B%0A%20%20%20%20%7D%0A%7D%0A” message=”” highlight=”” provider=”manual”/]

Looking at these functions we can see an error right off the bat:

  • setMag() has zero handling that it doesn’t need, we can cut that out

Other than that though, the code looks good! The problem appears to be with our perception, if both wind and gravity are equal and both are applied constantly the ball travels in a diagonal direction, but because the wind was intermittent before, gravity quickly accelerated the ball the max velocity, and in order to limit the magnitude of the vector and still increase velocity to the max allowable in one direction, we have to take away from one component, so as Y gets faster, X must get slower so the magnitude can increase as they are both linked!

We can more easily see what is happening by using smaller values for our gravity and higher values for our wind. Setting Wind to 5,0 and gravity to 0,.1 shows this well, the ball slowly accelerates to the limit and then if we add a burst of wind, it subtracts from the vertical speed and contributes to the lateral speed, once the wind is stopped, it begins accelerating downward again, slowly eroding the lateral speed.

Problem solved! The error was one of incorrect expectations!


Next up we can look at adding mass to our objects will will further complicate the mover object.

Leave a Reply

Your email address will not be published. Required fields are marked *