Rotation and translation: knowing when to stop

Started by
6 comments, last by Baiame 17 years, 1 month ago
Hello. I've been trying to think of ways to stop an entity from rotating or translating (in a non-instantaneous way), when it's "close enough" to its target. Of course, without such a check and the subsequent code, you get spasmodic flickering; the entity never quite reaches its target. Right now I'm doing something like this (the game is 2D at the moment):

 //direction angle recalculation
 newDirection.X=target.X-nodePos.X;
 newDirection.Y=target.Y-nodePos.Y;
 
 newDirection.normalize();
 direction.normalize();
 
 toAngle=direction.getAngle()+(360.0-newDirection.getAngle());
 if (toAngle>360.0) toAngle-=360.0;
 if (toAngle>180.0) toAngle=-(360.0-toAngle);

 
 //direction rotation
 if (toAngle!=0.0)
 {
    if (toAngle>0.0)
    {
    tempFloat=200.0*delta;
    direction.rotateBy(tempFloat, vector2df(0,0));
    toAngle-=tempFloat;
    if (toAngle<0.0)
    toAngle=0.0;
    }
    else
    {
    tempFloat=-200.0*delta;
    direction.rotateBy(tempFloat, vector2df(0,0));
    toAngle-=tempFloat;
    if (toAngle>0.0)
    toAngle=0.0;
    }
 }
Direction and newDirection are just vectors representing my entity's direction. The recalculation bit is some hackish stuff I worked out, as everything I tried involving dot and cross products of vectors failed. If you have a suggestion for a better way, I'd be happy to hear it. The rotation bit seemed like a good idea at the time. I thought the easiest way of resolving the "when to stop?" issue was to have a variable that stores the rotation needed, and take away the entity's rotation from that variable each loop, then test if it's above or below zero (depending on the direction of rotation). Turned out involving waaay more logical operators than I had expected, and you still get flickering when the rotation target changes each loop. So, what do you guys suggest?
Advertisement
Instead of testing against zero go until you're within some small epsilon of your target direction. That's what I'd try first.
^ If I interpret that correctly, I've done that before (in a simple way). It's hard to implement though. Considering that I can't guarantee a steady framerate, the range that the angle must be within clearly must vary with the delta time. I couldn't figure out a way to do it. I'd be grateful if you could explan how.

EDIT- I think I realized what's wrong with my method. It has to do with precision issues that come with dead-reckoning (with my toAngle variable). But all I know is that my previous method sucked, a better one would be much appreciated.
EDIT2- No, it was much simpler. I wasn't setting the direction vector to equal the new direction when the condition is met. My method was sound. Bah, I knew I was missing something there.

Still, I'd appreciate some input. Is it a good way to go for 2 axes of rotation in a 3D game (with NPC humans in mind)?

[Edited by - Baiame on March 7, 2007 2:47:14 PM]
Oh, and the question about translation still stands. What's the best way of checking if an entity is "close enough" to its intended destination?
distance check, or bounding box check if (x < worldx) etc
Black Sky A Star Control 2/Elite like game
^ But isn't a distance check somewhat limited? Consider again that you can't guarantee a steady framerate. Just a simple distance check would lead to inconsistencies; AIs might be quite a bit off from their waypoints in the end, and they might even overshoot.

I guess I could implement the time delta somehow (I suspect that's tricky, input on that would be nice). But something else I had in mind is physics-based movement. Things should be easy enough with infinite acceleration, but at some point I want the movement of all entities to be physical (using external libs). How can a rigid body possibly tell when it should stop applying a force to "land" at its destination? Considering the incline of the ground below it, smaller rigid bodies below it, and the different properties of the ground, it seems too much information to do a quick check on. How has it been done before?
When I do an overtime translation, I first calculate how far the destination is. Then, each frame, I'll decrease that by the amount moved that frame. Once the distance is epsilon or lower, I then jump the object to the desired destination, as it should be visually the same as if I let it move there itself, and I don't have to worry about floating point error, or overshooting.
^ Ah, so pretty much the same way I had originall planned on doing my rotation, then.

Sounds like it could work, but it's hard to reconcile with acceleration/deceleration/friction/slopes, etc. Thoughts? Thanks for your help so far, everyone.

This topic is closed to new replies.

Advertisement