def _with_rotation_about_axis( self: _T, angle: float, axis: np.ndarray, origin: np.ndarray, ) -> _T: """ Modify molecule. """ # Set the origin of the rotation to "origin". self._with_displacement(-origin) rot_mat = _utilities.rotation_matrix_arbitrary_axis( angle=angle, axis=axis, ) # Apply the rotation matrix on the position matrix, to get the # new position matrix. self._position_matrix = rot_mat @ self._position_matrix # Return the centroid of the molecule to the original position. self._with_displacement(origin) return self
def _with_rotation_to_minimize_angle( self: _T, start: np.ndarray, target: np.ndarray, axis: np.ndarray, origin: np.ndarray, ) -> _T: # If the vector being rotated is not finite, exit. This is # probably due to a planar molecule. if not all(np.isfinite(x) for x in start): return self if np.allclose(target, [0, 0, 0], atol=1e-15): raise ValueError( 'target has a magnitude of 0. It is therefore not ' 'possible to calculate an angle.') self._with_displacement(-origin) # 1. Remove any component of the start and target vectors long # the axis. This puts them both on the same plane. # 2. Calculate the angle between them. # 3. Apply the rotation. tstart = start - np.dot(start, axis) * axis # If `tstart` is 0, it is parallel to the rotation axis, stop. if np.allclose(tstart, [0, 0, 0], 1e-8): self._with_displacement(origin) return self tend = target - np.dot(target, axis) * axis # If `tend` is 0, it is parallel to the rotation axis, stop. if np.allclose(tend, [0, 0, 0], 1e-8): self._with_displacement(origin) return self angle = _utilities.vector_angle(tstart, tend) projection = tstart @ np.cross(axis, tend) if projection > 0: angle = 2 * np.pi - angle rotation_matrix = _utilities.rotation_matrix_arbitrary_axis( angle=angle, axis=axis, ) self._position_matrix = rotation_matrix @ self._position_matrix self._with_displacement(origin) return self
def _with_rotation_about_axis(self, angle, axis, origin): """ Modify molecule. """ # Set the origin of the rotation to "origin". self._with_displacement(-origin) rot_mat = rotation_matrix_arbitrary_axis(angle, axis) # Apply the rotation matrix on the position matrix, to get the # new position matrix. self._position_matrix = rot_mat @ self._position_matrix # Return the centroid of the molecule to the original position. self._with_displacement(origin) return self