docs: def vector_angle(u, v, direction=None):
      '''
      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).
      '''
      if direction is None:
          return np.arccos(vector_angle_cos(u, v))
      elif direction is True:
          return np.arctan2(v[1], v[0]) - np.arctan2(u[1], u[0])
      elif direction is False:
          return np.arctan2(u[1], u[0]) - np.arctan2(v[1], v[0])
      else:
          axis1 = normalize(u)
          axis2 = normalize(np.cross(u, v))
          if np.dot(axis2, direction) < 0:
              axis2 = -axis2
          return np.arctan2(np.dot(axis2, v), np.dot(axis1, v))