Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Given a body with an orientation angle and a point of interest or targetAngle, is there an elegant solution for keeping the body oriented towards the point of interest by applying torque or impulses?

I have a naive solution working below, but the effect is pretty 'wobbly', it'll overshoot each time, slowly getting closer to the target angle - an undesirable effect in my case. I'd like to find a solution that is more intelligent - one that can accelerate to near the target angle then decelerate and stop right at the target angle (or within a small range).

If it helps, I'm using box2d and the body is a rectangle.

def gameloop(dt):
    targetAngle = get_target_angle()
    bodyAngle = get_body_angle()
    deltaAngle = targetAngle - bodyAngle
    if deltaAngle > PI:
        deltaAngle = targetAngle - (bodyAngle + 2.0 * PI)
    if deltaAngle < -PI:
        deltaAngle = targetAngle - (bodyAngle - 2.0 * PI)
    # multiply by 2, for stronger reaction
    deltaAngle = deltaAngle * 2.0;
    body.apply_torque(deltaAngle);

One other thing, when body has no linear velocity, the above solution works ok. But when the body has some linear velocity, the solution above causes really wonky movement. Not sure why, but would appreciate any hints as to why that might be.

share|improve this question
    
Without actually looking at your code, I'd guess you need some PID. –  muntoo Dec 31 '10 at 1:12
    
@muntoo - what is PID? –  azymm Dec 31 '10 at 4:12
1  
A google search gave me either en.wikipedia.org/wiki/PID_controller or en.wikipedia.org/wiki/Pelvic_inflammatory_disease . And I don't think it's the second one. –  The Communist Duck Dec 31 '10 at 13:31
    
Could you explain more about the "wonky" movement? –  ChrisE May 9 '11 at 21:37

1 Answer 1

From what I've understood from your post, this is essentially an Arrive behaviour. Arrival is a fairly simple behaviour to implement, and you don't have to use angles to get an angle back either.

Vector toTargetVector = targetPosition - bodyPosition;
double distanceToTarget = toTargetVector.Length();

// It's very simple to get the angle from here, just use atan2 (or the equivalent function in whatever language you're using)
float angleToTarget = atan2( toTargetVector.y, toTargetVector.x );

if( distanceToTarget > 0.0 )
{
    double rateOfDeceleration = 0.2;    // This can be tweaked to whatever value you like
    double speed = distanceToTarget / rateOfDeceleration;

    Vector desiredVelocity = ( toTargetVector * speed ) / distanceToTarget;

    return ( desiredVelocity - body.velocity );
}

This behaviour (among the rest of them) is very clearly detailed in Mat Buckland's book "Programming Game AI by Example".

If you want a very, very simple behaviour just to get your target angle correct then use Seek.

Vector toTargetVector = targetPosition - bodyPosition;

double distanceToTarget = toTargetVector.Length();

float angleToTarget = atan2( toTargetVector.y, toTargetVector.x );

And that's basically it, you can then do all your physics stuff after this basic vector stuff.

Hope that helps.

share|improve this answer
    
Thanks for the book reference. I'll check that out. I guess I am trying to do a Seek behavior, but I was trying to avoid setting velocity, position and rotation explicitly because it could interfere with the box2d simulation. Instead I was trying to maneuver the body by applying impulses, torque and/or force (proving to be difficult for me). Also, I'm trying to align the body's orientation with its velocity. –  azymm Dec 31 '10 at 3:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.