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.

I'm looking for an easy way to achieve the following:

Object A, B
{
    Vector2D position;
    Vector2D orientation;
}

update(elapsed)
{
    //rotate A's orientation in B's direction by x * elapsed degrees
    //until A's orientation equals the direction from A to B
}

I am trying to align object A with an object B. Object A should rotate in B's direction by certain degrees/sec, e.g. max 45/sec.

I calculate the direction from A to B with normalize(B.position - A.position), but I don't know how to rotate A's orientation vector stepwise in B's direction.

share|improve this question
add comment

4 Answers

You could always deploy a type of Linear Interpolation. This allows you to slowly move to the target rotation over time and make it look decent.

If I'm misunderstanding and you simply want the angle between the two vectors, you might want to first normalize them (as you have done) and then simply take the dot product and angle. You can find a StackOverflow post on the topic over here, it's written in PHP but very easily read for any language.

share|improve this answer
1  
In addition, some engines already have build in linear interpolation functions (e.g. lerp in unity3d). –  Adam S May 26 '13 at 14:01
add comment

Finally I solved my issue as follows:

update(double elapsed)
{
double targetAngle = Math.atan2(B.position.y - position.y, B.position.x - position.x);
double currentAngle = orientation.toRadians();

//Calculate angular deviation
double deviation = targetAngle - currentAngle;
double absDeviation = (deviation < 0 ? -deviation : deviation);

double maxRotation = maxRad * elapsed;

//If the absolute deviation is less than max rotation, rotate by.
//Else rotate the allowed radians in B's direction.
if(absDeviation <= maxRotation)
    orientation.rotate(deviation);
else
    orientation.rotate(Math.signum(deviation) * maxRotation);
}

Thank you for your time.

share|improve this answer
add comment
  1. Convert the desired degrees/second to radians/frame;
  2. Calculate the rotation matrix M (if 3D, about the cross-product A x B, else about the Z-axis) for the value calculated in (1) above;
  3. Each frame, generate a new A from the previous frame's A * M.

Are you familiar with (1) use of homogeneous matrices and (2) converting a rotation matrix about the origin to a rotation matrix about some other point in the plane?

share|improve this answer
add comment

thank you for your answers.

Linear interpolation sounds interesting, but I wasn't able to solve my problem with it. What I didn't mention in my question is that object B can change its position while A is aligning to it, so the adjustment of the interpolation scalar seemed quite difficult to me. (e.g. if the angle between both objects increases, the interpolated vector "moves" faster)

I extended my vector class by the following function which should be equivalent to multiplying the vector by a 2x2 rotation matrix:

public Vector2D rotate(double radians)
{
    double x = this.x * Math.cos(radians) - this.y * Math.sin(radians);
    double y = this.x * Math.sin(radians) + this.y * Math.cos(radians);
    this.x = x;
    this.y = y;
    return this;
}

If I call rotate(desiredRadians * elapsed) on A's orientation vector, the rotation works fine.

I still don't know how to stop the rotation when the desired direction (or angle) is reached. Also A would ideally rotate in the "shorter" and not necessarily in clockwise direction (e.g. prefer a rotation by -90 to +270 degrees).

Thank you.

share|improve this answer
add comment

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.