0
$\begingroup$

For my 2D physics engine, I'm using the unit vectors of the direction an object is facing to represent its orientation; essentially, [Cos(theta),Sin(theta)] where theta is the object's rotation in angles. This makes it very easy for me to make an object face a target but it's difficult to increment the rotation. With angles, what I want to achieve is this:

//progress is the interpolation value from 0 to 1

rotation = startRotation * (1-progress) + targetRotation * progress;

How can I do something something similar with unit vector direction? Note: I'd rather not use inverse trig functions because they're expensive and imprecise.

$\endgroup$

2 Answers 2

1
$\begingroup$

Use a rotation matrix. Assuming that your rotation increment is constant then let $d\theta = (targetRotation - startRotation)/n$ where $n$ is the number of steps you wish to take. Then your incremental rotation matrix could be computed once as follows:

$$R = \left[ \begin{array}{cc} \cos d\theta & -\sin d\theta \\ \sin d\theta & \cos d\theta \end{array} \right]$$

then your update step would simply be:

$$u_{k+1} = Ru_k$$

where $u$ is your unit vector. I assume that you know how to create and multiply matrices and vectors in your programming language of choice.

$\endgroup$
1
  • $\begingroup$ Thanks! I did something based on this where I just use the clockwise/counterclockwise rotation matrices, added the result to the current rotation * mass, then normalized the new vector. $\endgroup$
    – JPtheK9
    Apr 1, 2015 at 23:09
0
$\begingroup$

I did something based on tpofofn's answer which is using the current rotation turned clockwise/counter-clockwise as the base unit for incrementing. Actually, I didn't need a rotation matrix because rotating a vector clockwise 90deg is just vec = new vector(-vec.y,vec.x).

I added this to the body's current rotation times so the higher the mass, the less the increment. To find which way to rotate, I used the dot product of the rotation's turned 90deg clockwise and the target orientation. This is an example that increments the rotation towards the direction the object is moving in.

//Get the base increment
Vector right = new Vector(-body.rotation.y,body.rotation.x);
//Find out which way to turn
Int direction = Vector.Dot(right,body.velocity);
//Increment in the direction to turn based on mass
body.rotation = (right * direction + body.rotation * body.mass).normalized;

and I did a further check to make sure the rotation doesn't overshoot and wobble back and forth.

right = new Vector(-body.rotation.y,body.rotation.x);
if (Vector.Dot(right,body.velocity) == -direction)
{
    body.rotation = body.velocity.normalized;
}

Theoretically, rotational velocity can be applied like this as well by multiplying the base increment by the rotation speed) but my game is an RTS so I have no need for it. The main benefit of using rotation vectors and rotating them this way is that there's no expensive trigonometry involved.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .