def rotation_of(source, dest): """ Returns a :class:`Quaternion` that represents a rotation from vector *source* to *dest*. :param source: A vector object. :param dest: A vector object. :return: :class:`Quaternion` """ source = Vector(source.x, source.y, source.z) dest = Vector(dest.x, dest.y, dest.z) cross = source.cross(dest) cos_theta = source.dot(dest) # Return identity if the vectors are the same direction. if cos_theta >= 1.0: return Quaternion.identity() # Product of the square of the magnitudes. k = math.sqrt(source.dot(source), dest.dot(dest)) # Return identity in the degenerate case. if k <= 0.0: return Quaternion.identity() # Special handling for vectors facing opposite directions. if cos_theta / k <= -1: x_axis = Vector(1, 0, 0) y_axis = Vector(0, 1, 1) if abs(source.dot(x_ais)) < 1.0: cross = source.cross(x_axis) else: cross = source.cross(y_axis) return Quaternion(cross.x, cross.y, cross.z, k + cos_theta)
def rotation_of(source, dest): """ Returns a :class:`Quaternion` that represents a rotation from vector *source* to *dest*. :param source: A vector object. :param dest: A vector object. :return: :class:`Quaternion` """ source = Vector(source.x, source.y, source.z) dest = Vector(dest.x, dest.y, dest.z) cross = source.cross(dest) cos_theta = source.dot(dest) # Return identity if the vectors are the same direction. if cos_theta >= 1.0: return Quaternion.identity() # Product of the square of the magnitudes. k = math.sqrt(source.dot(source), dest.dot(dest)) # Return identity in the degenerate case. if k <= 0.0: return Quaternion.identity() # Special handling for vectors facing opposite directions. if cos_theta / k <= -1: x_axis = Vector(1, 0, 0) y_axis = Vector(0, 1, 1) if abs(source.dot(x_ais)) < 1.0: cross = source.cross(x_axis) else: cross = source.cross(y_axis) return Quaternion(cross.x, cross.y, cross.z, k + cos_theta)