-> > Here's how I usually code it in QBasic.
-> >
-> > FUNCTION Ang(X, Y)
-> > SELECT CASE SGN(X)
-> > CASE 1: Ang = ATN(Y / X)
-> > CASE -1: Ang = ATN(Y / X) + PI
-> > CASE ELSE: Ang = SGN(Y) * PI / 2
-> > END SELECT
-> > END FUNCTION
-> >
-> > Of course PI has to be pre-defined.
-> >
-> > The FUNCTION produces an angle in the range -PI/2 <= Ang < 3*PI/2.
-> > That's the complete circle, but if you want to adjust the range to,
-> > e.g., 0 to 2*PI, you'd have to add a bit of fiddling.
-> >
-> > Note that Ang is *not* equal to ATN(Y/X) if X is negative. ATN
doesn't
-> > produce the complete circle of values.
-> Most implementations give
-> ATAN2(-5,-5) = -2.35619
-> but yours gives
-> Ang(-5,-5) = 3.926990
-> Any idea why?
-> Tom L
Sure. As I said this morning, the FUNCTION produces an angle in the
range -PI/2 to 3*PI/2 radians. That's a perfectly good range. If the
defined point, (-5, -5) in your case, is in the "third quadrant", i.e.
the bottom-left quarter of the plane, the quarters being defined by the
axes, then it will come up with an angle between PI and 3*PI/2 radians,
which is what you have found. However, it is equally valid, for
example, to define the range as -PI to PI, so the angle we are looking
at is measured in the *clockwise*, i.e. negative, direction from the
positive X-axis. So the angle comes out between -PI/2 and -PI, which is
what your "other implementations" produce.
Neither is "right" or "wrong". It's just a matter of the choice of
range, which can be anything that is 2*PI radians from one end to the
other. Here's a little variation that allows the range to ba varied:
FUNCTION Ang(X, Y)
SELECT CASE SGN(X)
CASE 1: A = ATN(Y / X)
CASE -1: A = ATN(Y / X) + PI
CASE ELSE: A = SGN(Y) * PI / 2
END SELECT
IF A > PI THEN A = A - 2 * PI
Ang = A
END FUNCTION
The only real difference between this and the version I posted this
morning is the IF line near the end. It subtracts 2*PI, i.e. a complete
rotation, from the angle if it is greater than PI. The result is that
the FUNCTION in the above form outputs angles in the range -PI to PI.
This is, I think, what your "other implementations" do.
There are other options. You could change the IF line to:
IF A < 0 THEN A = A + 2 * PI
This adds a rotation to negative angles, and has the effect of making
the function output in the range 0 to 2*PI.
None of these is more "correct" than any of the others. However, in
some contexts, one of them may be more *convenient* than the others.
Usually, I find that the FUNCTION in the simple form that I wrote this
morning does everything I need. However, if I require the angle to be
in some other range, then the other options (an unlimited number of
them) are available.
dow


|