Roel Schroeven wrote: > > I might be wrong of course, but can't you just use atan2? Only problem > is that it returns negative angles for quadrants 3 and 4, but that is > easily solved. In Python: > > from math import atan2, pi, fmod > def vectorAngle(x, y): > return fmod(atan2(y, x) + 2*pi, 2*pi) > > No conditionals in sight. >
Yes, but there will be some conditionals for special cases in the implementation of atan2(). I am pretty sure that in Python (and Perl) atan2() is the C atan2() from the C math library, also often used by Fortran. This is normally written in assembler for the individual architecture by the hardware vendor or compiler writer, is usually heavily optimized, carefully handles all the corner cases, and often carries extra precision to ensure accuracy. If I recall correctly P. J. Plauger's book on the C standard library ("The Standard C Library") includes a C version of atan2(), which is probably pretty typical of the algorithms used when there is no hardware support for trigonometric functions. As I remember it, atan2 (and atan) in Plauger's book use a ratio of polynomials to approximate atan(x) over a limited range, (such as -1.0 ... +1.0 or 0.0 ... sqrt(2)-1) and formulae (assuming I have remembered high school trigonometry correctly) such as atan(x) = pi/2 - atan(1/x) and atan(x) = pi/4 - atan((1-x)/(1+x)) [derived from tan(pi/4-x) = (1-x)/(1+x)] to extend the range. There is an obvious trade off between the complexity of the approximating polynomials (and the range they cover with acceptable accuracy), and the number of cases needed to extend the range to all valid inputs. For example, if the polynomials cover -1.0 ... +1.0 (atan() values of -pi/4 to +pi/4) then there are at least 5 cases to consider (atan() ranges -pi ... -3pi/4, -3pi/4 ... -pi/4, -pi/4 ... +pi4, +pi/4 ... +3pi/4, +3pi/4 ... +pi), while if the approximations only cover 0.0 ... sqrt(2)-1 (atan() values from 0.0 to pi/8) then there are at least 16 cases. NaNs and infinities would add additional cases, as may the need to preserve accuracy near zero. Charles -- http://mail.python.org/mailman/listinfo/python-list