How do I convert an Angle to the range [-pi,pi]?

Started by
16 comments, last by navderm 11 years, 6 months ago
Quote:If there's a little chance for a bigger increment to occur, then you could use a loop (a clever loop, which I can't think of now...).


How can this clever Loop be faster than the fmod() Division loop? If I decrement 2pi in each Iteration that's pretty much what fmod() does.
Advertisement
Quote:Original post by Emergent
I'll note that fmod is pretty slow, and so is atan2(sin, cos). I find that most of the time I need to rewrap angles, it occurs in situations where I know that I will only need to either add of subtract 2*pi once from my angle to get one in the range I want -- and I find that this code is noticeably faster.
And he has so many rate points! :P

That's why I suggested to to distinguish between small, and big increments (The second half of the post you quoted)
Quote:Original post by alvaro
As has been mentioned in this forum many times, you can probably do whatever you are doing without using angles. Representing a 2D heading as a unit vector often results in code that is much cleaner (fewer corner cases to consider) and faster to execute.

If you are familiar with complex numbers, you can also think of that 2D unit vector as a complex number, since multiplying by it results in the correct rotation.


I don't usually follow the Physics Forum, only at the Moment.
Let's say my current Heading is given by the Vector
(cos(pi), sin(pi))
How do I rotate this vector 0.02 Radians using the Unit Vector Method?

Another task I need to perform is to calculate the Angle of a foreign Object in my Local Referencial and I am currently doing it with Angles:
float Localtargetangle = ::atan2 ( Relativetargetposition.Y,Relativetargetposition.X ) - Orientation ;Localtargetangle = ::atan2 ( ::sin ( Localtargetangle ),::cos ( Localtargetangle ) ) ;

If you can teach me how to do these 2 Tasks using the Vector Method I will appreciate it.
Quote: Original post by hiigara
How do I rotate this vector 0.02 Radians using the Unit Vector Method?



You can rotate the vector like this:
Vector2D rotate(Vector2D const &v, double angle) {

double cosine = std::cos(angle), sine = std::sin(angle);

return Vector2D(cosine*v.x - sine*v.y, sine*v.x + cosine*v.y);

}

If you do it using complex numbers, it becomes:
std::complex<double> rotate(std::complex<double> z, double angle) {

return z * std::complex<double>(std::cos(angle), std::sin(angle));

}

Or even:
std::complex<double> rotate(std::complex<double> z, double angle) {

return z * std::exp(std::complex<double>(0,angle));

}


Quote: Another task I need to perform is to calculate the Angle of a foreign Object in my Local Referencial and I am currently doing it with Angles:
*** Source Snippet Removed ***



This kind of operation is very easy with complex numbers:
std::complex<double> rotation_that_turns_A_into_B(std::complex<double> A, std::complex<double> B) {

std::complex<double> result = B/A;

return result/std::abs(result);

}



If I had to do it with 2D vectors, I would simply expand the formula for complex division.
Thanks everyone.
Alvaro one last Question. Do I have to "renormalize" my Orientation Vector before using it?

Vct = rotate ( Vct, 0.02 ) ;
Vct = Vct / Vct.length () ;
Position = Position + Vct * Speed ;

I think it will deviate from Norm 1 due to Error Propagation.
Quote:Original post by hiigara
Thanks everyone.
Alvaro one last Question. Do I have to "renormalize" my Orientation Vector before using it?

Vct = rotate ( Vct, 0.02 ) ;
Vct = Vct / Vct.length () ;
Position = Position + Vct * Speed ;

I think it will deviate from Norm 1 due to Error Propagation.


Yep, what you wrote is exactly what people do. Error propagation is the reason as you said.

If you do it using complex numbers, it becomes:
std::complex<double> rotate(std::complex<double> z, double angle) {
return z * std::complex<double>(std::cos(angle), std::sin(angle));
}

Or even:
std::complex<double> rotate(std::complex<double> z, double angle) {
return z * std::exp(std::complex<double>(0,angle));
}


Or even:
std::complex<double> rotate(std::complex<double> z, double angle) {
return z * std::polar(1.0,angle);
}


If you do it using complex numbers, it becomes:
std::complex<double> rotate(std::complex<double> z, double angle) {
return z * std::complex<double>(std::cos(angle), std::sin(angle));
}

Or even:
std::complex<double> rotate(std::complex<double> z, double angle) {
return z * std::exp(std::complex<double>(0,angle));
}


Or even:
std::complex<double> rotate(std::complex<double> z, double angle) {
return z * std::polar(1.0,angle);
}

inline void convertToQuad2(double& theta)
{
if (theta > -PI/2 && theta < PI/2)
return;
if (theta < -PI/2)
{
theta = theta + PI;
convertToQuad2(theta);
}
if (theta > PI/2)
{
theta = theta - PI;
convertToQuad2(theta);
}
}

int main ()
{
convertToQuad(12.423);
}

This topic is closed to new replies.

Advertisement