def get_vector_perp_to_p_and_q(p, q): """p and q are distinct points on sphere, return a unit vector perpendicular to both""" if abs(dot(p,q) + 1) < 0.0001: ### deal with the awkward special case when p and q are antipodal on the sphere if abs(dot(p, vector([1,0,0]))) > 0.9999: #p is parallel to (1,0,0) return vector([0,1,0]) else: return cross(p, vector([1,0,0])).normalised() else: return cross(p, q).normalised()
def get_vector_perp_to_p_and_q(p, q): """p and q are distinct points on sphere, return a unit vector perpendicular to both""" if abs( dot(p, q) + 1 ) < 0.0001: ### deal with the awkward special case when p and q are antipodal on the sphere if abs(dot(p, vector([1, 0, 0]))) > 0.9999: #p is parallel to (1,0,0) return vector([0, 1, 0]) else: return cross(p, vector([1, 0, 0])).normalised() else: return cross(p, q).normalised()
def rotate_sphere_points_p_to_q(p, q): """p and q are points on the sphere, return SL(2,C) matrix rotating image of p to image of q on CP^1""" p, q = vector(p), vector(q) CP1p, CP1q = CP1_from_sphere(p), CP1_from_sphere(q) if abs(dot(p, q) - 1) < 0.0001: return [[1, 0], [0, 1]] else: r = get_vector_perp_to_p_and_q(p, q) CP1r, CP1mr = CP1_from_sphere(r), CP1_from_sphere(-r) return two_triples_to_SL(CP1p, CP1r, CP1mr, CP1q, CP1r, CP1mr)
def zoom_along_axis_sphere_points_p_q(p, q, zoom_factor): """p and q are points on sphere, return SL(2,C) matrix zooming along axis from p to q""" p, q = vector(p), vector(q) CP1p, CP1q = CP1_from_sphere(p), CP1_from_sphere(q) assert dot(p,q) < 0.9999 #points should not be in the same place r = get_vector_perp_to_p_and_q(p, q) CP1r = CP1_from_sphere(r) M_standardise = two_triples_to_SL(CP1p, CP1q, CP1r, [0,1], [1,0], [1,1]) M_theta = [[zoom_factor,0],[0,1]] return matrix_mult( matrix_mult(matrix2_inv(M_standardise), M_theta), M_standardise )
def rotate_around_axis_sphere_points_p_q(p,q,theta): """p and q are points on sphere, return SL(2,C) matrix rotating by angle theta around the axis from p to q""" p, q = vector(p), vector(q) CP1p, CP1q = CP1_from_sphere(p), CP1_from_sphere(q) assert dot(p,q) < 0.9999, "axis points should not be in the same place!" r = get_vector_perp_to_p_and_q(p, q) CP1r = CP1_from_sphere(r) M_standardise = two_triples_to_SL(CP1p, CP1q, CP1r, [0,1], [1,0], [1,1]) M_theta = [[complex(cos(theta),sin(theta)),0],[0,1]] #rotate on axis through 0, infty by theta return matrix_mult( matrix_mult(matrix2_inv(M_standardise), M_theta), M_standardise )
def rotate_sphere_points_p_to_q(p, q): """p and q are points on the sphere, return SL(2,C) matrix rotating image of p to image of q on CP^1""" p, q = vector(p), vector(q) CP1p, CP1q = CP1_from_sphere(p), CP1_from_sphere(q) if abs(dot(p,q) - 1) < 0.0001: return [[1,0],[0,1]] else: r = get_vector_perp_to_p_and_q(p, q) CP1r, CP1mr = CP1_from_sphere(r), CP1_from_sphere(-r) return two_triples_to_SL(CP1p, CP1r, CP1mr, CP1q, CP1r, CP1mr)
def zoom_along_axis_sphere_points_p_q(p, q, zoom_factor): """p and q are points on sphere, return SL(2,C) matrix zooming along axis from p to q""" p, q = vector(p), vector(q) CP1p, CP1q = CP1_from_sphere(p), CP1_from_sphere(q) assert dot(p, q) < 0.9999 #points should not be in the same place r = get_vector_perp_to_p_and_q(p, q) CP1r = CP1_from_sphere(r) M_standardise = two_triples_to_SL(CP1p, CP1q, CP1r, [0, 1], [1, 0], [1, 1]) M_theta = [[zoom_factor, 0], [0, 1]] return matrix_mult(matrix_mult(matrix2_inv(M_standardise), M_theta), M_standardise)
def rotate_around_axis_sphere_points_p_q(p, q, theta): """p and q are points on sphere, return SL(2,C) matrix rotating by angle theta around the axis from p to q""" p, q = vector(p), vector(q) CP1p, CP1q = CP1_from_sphere(p), CP1_from_sphere(q) assert dot(p, q) < 0.9999, "axis points should not be in the same place!" r = get_vector_perp_to_p_and_q(p, q) CP1r = CP1_from_sphere(r) M_standardise = two_triples_to_SL(CP1p, CP1q, CP1r, [0, 1], [1, 0], [1, 1]) M_theta = [[complex(cos(theta), sin(theta)), 0], [0, 1]] #rotate on axis through 0, infty by theta return matrix_mult(matrix_mult(matrix2_inv(M_standardise), M_theta), M_standardise)