Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #3
0
    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