Strange behaviour when velocity nears 0

Started by
4 comments, last by Toji 18 years, 10 months ago
I'm kinda stumped here. I've been working on a simple, 2D physics implementation (visual c++ and OpenGL) and have had a lot of success so far with one exception: When the velocity of any dynamic entity get's close to zero (That is, the x and y components are both very small), the entity will simply dissapear. After a bit of digging through debug info, I've found that (as I suspected) what actually is happening is instead of going to (0, 0) as I would expect, the vector suddenly jumps to ( -1.#IND00, -1.#IND00 ) according to the debugger. I strongly suspect that the reason I'm getting this is simply my lack of understanding as to how floats work (my vectors are defines as two floats: x and y) I have gone through and made sure that there's no divides or modulates in the code, or anything that seems like it could cause the numbers to blow up like so. I feel like it's a very simple thing I'm missing (like I said, proably just the result of my lack of understanding of how floats are stored) so if anyone can point out what I may be missing I'd be grateful! (I don't have the time now, but I'll post code tomorrow if no one has any ideas.) Thanks!
// The user formerly known as Tojiro67445, formerly known as Toji [smile]
Advertisement
check your integrator. this happens a lot with euler. if you do a step between your euler then calculate the average of the derivatives and use that instead, you can reduce your error O(h^2) as opposed to O(h), where h=stepsize. in otherwords, 4x more accurate. if you use RK4, you get O(h^4), 16x better approximatons. no matter what, you are still playing with approximations, so you definately want to look for somewhere in your code where you divide something by your velocity then feed that into something else. that is probably where the problem is.
"a low level aho master like you couldn't kill me even if I let you"
It realy could be anything. division by zero maybe, or usage of an uninitialized variable?

Search for the name of the velocity var and go through every piece of code where it is used. If you don't find it yourself that way then you could print the vector to console every time it is altered.

printf("----------------------------------\n");printf("void integrate()\n"); // name of function where velocity var is usedprintf("x: %f\ty: %f\tz: %f\n", velocity.x, velocity.y, velocity.z);// use velocity in your codevelocity += acceleration * dt;printf("x: %f\ty: %f\tz: %f\n", velocity.x, velocity.y, velocity.z);printf("----------------------------------\n");

Now when/if the bug appear you shut down the main window and go through the console searching for the first velocity output with invalid values. When you find that you will also have the name of the function where the bug is (assuming it is only one bug). You could also print velocity to a file.
You could be normalizing velocity in order to calculate the 'facing' direction.

Also you can set a 'memory breakpoint' on the vector and it'll break each time the value changes. You can set a condition on it #IND0'ing (0xFF000000 probably?), or you can just keep hitting F5 til you see it go wonkers.

The way I do this is to break while the program is running and look at the address of the variable you want to watch (say 0x7000f034). Click 'Create New Breakpoint' and select on the 'Data' tab, and in the variable field set *(float *)0x7000f034 ... Then every time the value at that address changes, the program will break into the debugger (So you'd only want this bp enabled when you feel the bug is about to happen).
it's a 0 divide by 0 all right, so sounds like a normalisation of the velocity vector.

0 / 0 = indeterminate.

Else, for a division by 0, it would return 1.#INF0 instead of -1.#IND.

Another classic is doing acos(1.00001f);

1 / 0 = 1.#INF
0 / 0 = -1.#IND
acos(1.00001f) = -1.#IND

Everything is better with Metal.

Thank you everyone for such quick responses. I think I've finally got it! My problem turns out to be that even though I've meticulously avaoided the possibility of Divide by 0 errors when updating my velocity I forgot to do it in the one place that was causing me a problem!

When a collision was detected I would push the entity back with a "push vector" (I've been using your tutorials, Oliii), and would then normalize that push vector to find the angle that we're bouncing off at. That normalize was what did it, as when the velocity reached zero it would have to push back with a vector of near zero length. Putting a quick catch in the code cleared that up right away!

Thanks again!
// The user formerly known as Tojiro67445, formerly known as Toji [smile]

This topic is closed to new replies.

Advertisement