def vector_angle(u, v, direction=None):
if direction is None:<EOL><INDENT>return np.arccos(vector_angle_cos(u, v))<EOL><DEDENT>elif direction is True:<EOL><INDENT>return np.arctan2(v[<NUM_LIT:1>], v[<NUM_LIT:0>]) - np.arctan2(u[<NUM_LIT:1>], u[<NUM_LIT:0>])<EOL><DEDENT>elif direction is False:<EOL><INDENT>return np.arctan2(u[<NUM_LIT:1>], u[<NUM_LIT:0>]) - np.arctan2(v[<NUM_LIT:1>], v[<NUM_LIT:0>])<EOL><DEDENT>else:<EOL><INDENT>axis1 = normalize(u)<EOL>axis2 = normalize(np.cross(u, v))<EOL>if np.dot(axis2, direction) < <NUM_LIT:0>:<EOL><INDENT>axis2 = -axis2<EOL><DEDENT>return np.arctan2(np.dot(axis2, v), np.dot(axis1, v))<EOL><DEDENT>
vector_angle(u, v) yields the angle between the two vectors u and v. The optional argument 
direction is by default None, which specifies that the smallest possible angle between the
vectors be reported; if the vectors u and v are 2D vectors and direction parameters True and
False specify the clockwise or counter-clockwise directions, respectively; if the vectors are
3D vectors, then direction may be a 3D point that is not in the plane containing u, v, and the
origin, and it specifies around which direction (u x v or v x u) the the counter-clockwise angle
from u to v should be reported (the cross product vector that has a positive dot product with
the direction argument is used as the rotation axis).