BRG said:
Robert said:
BRG wrote:
Mr. Ken wrote:
I am calculating the phase of an IQ signal, which are polluted by AWGN
gaussian noise.
As well as having the function atan(x), your system is likely to have
atan2(y, x) which eliminates the ambiguity except when x and y are both
zero.
atan2 avoids infinity, and I think gives a full +/-pi range, but there's
still a massive jump in the number that represents phase, so you can't
just average that number to remove noise.
[snip]
You can at +pi/2 and -pi/2, the points to which the original poster
specifically referred.
When two quadrature signals I and Q are available, atan2(Q, I) is better
than atan(Q/I) since it not only eliminates the division by zero problem
but also eliminates the artificial phase ambiguity _introduced_ by
atan(Q/I) at +pi/2 and -pi/2.
Noise will still be an issue at +pi and -pi but at least atan2(Q, I)
won't produce the incorrect results given by atan(Q/I) near +pi/2 and
-pi/2 caused by essentially ignoring a good sign on Q when I is small.
Hmm... Let's see how much of this mess it cleans up:
float CalcTheta( const JVEC2 Point1, const JVEC2 Point2 )
{
float Theta;
if ( Point2.x - Point1.x == 0 )
if ( Point2.y > Point1.y )
Theta = 0;
else
Theta = static_cast<float>( PI );
else
{
Theta = std::atan( (Point2.y - Point1.y) / (Point2.x - Point1.x) );
if ( Point2.x > Point1.x )
Theta = static_cast<float>( PI ) / 2.0f - Theta;
else
Theta = static_cast<float>( PI ) * 1.5f - Theta;
};
return Theta;
}
would become...
float CalcTheta( const JVEC2 Point1, const JVEC2 Point2 )
{
float Theta;
Theta = std::atan2( (Point2.y - Point1.y) / (Point2.x - Point1.x) );
if ( Point2.x > Point1.x )
Theta = static_cast<float>( PI ) / 2.0f - Theta;
else
Theta = static_cast<float>( PI ) * 1.5f - Theta;
};
return Theta;
}
Is that all that can be simplified?