def get_rotations(normal): x = np.array([1,0,0]); y = np.array([0,1,0]); z = np.array([0,0,1]) yz_proj = np.dot(y, normal)*y + np.dot(z, normal)*z # <z, yz_proj> = vnorm(z)*vnorm(yz_proj)*cos(theta) theta = np.arccos( np.dot(z, yz_proj)/vnorm(yz_proj) ) xz_proj = np.dot(x, normal)*x + np.dot(z, normal)*z psi = -np.arccos( np.dot(z, xz_proj)/vnorm(xz_proj) ) xy_proj = np.dot(x, normal)*x + np.dot(y, normal)*y phi = np.arccos( np.dot(y, xy_proj)/vnorm(xy_proj) ) return util.eulerRot(theta=theta, psi=psi, phi=phi)
def get_rotations(normal): x = np.array([1, 0, 0]) y = np.array([0, 1, 0]) z = np.array([0, 0, 1]) yz_proj = np.dot(y, normal) * y + np.dot(z, normal) * z # <z, yz_proj> = vnorm(z)*vnorm(yz_proj)*cos(theta) theta = np.arccos(np.dot(z, yz_proj) / vnorm(yz_proj)) xz_proj = np.dot(x, normal) * x + np.dot(z, normal) * z psi = -np.arccos(np.dot(z, xz_proj) / vnorm(xz_proj)) xy_proj = np.dot(x, normal) * x + np.dot(y, normal) * y phi = np.arccos(np.dot(y, xy_proj) / vnorm(xy_proj)) return util.eulerRot(theta=theta, psi=psi, phi=phi)
def nearest_simple_transform(M): """Finds the closest transformation to M that is composed of only n*(PI/2) rotations and axis reflections. """ # if det(M) < 0, then M has some reflections going on (which is still fine) tag = np.linalg.det(M) < 0 and -1 or 1 M[:,2] *= tag (theta, psi, phi) = decompose_rot(M) angs = np.array([theta, psi, phi]) angs = np.pi/2 * ((angs + np.sign(angs)*np.pi/4)/(np.pi/2)).astype('i') M2 = eulerRot(theta=angs[0], psi=angs[1], phi=angs[2]) M[:,2] *= tag M2[:,2] *= tag return M2