Beispiel #1
0
def compose_matrix(scale=None,
                   shear=None,
                   angles=None,
                   translation=None,
                   perspective=None):
    """Calculates a matrix from the components of scale, shear, euler_angles,
    translation and perspective.

    Parameters
    ----------
    scale : :obj:`list` of :obj:`float`
        The 3 scale factors in x-, y-, and z-direction.
    shear : :obj:`list` of :obj:`float`
        The 3 shear factors for x-y, x-z, and y-z axes.
    angles : :obj:`list` of :obj:`float`
        The rotation specified through the 3 Euler angles about static x, y, z axes.
    translation : :obj:`list` of :obj:`float`
        The 3 values of translation.
    perspective : :obj:`list` of :obj:`float`
        The 4 perspective entries of the matrix.

    Examples
    --------
    >>> trans1 = [1, 2, 3]
    >>> angle1 = [-2.142, 1.141, -0.142]
    >>> scale1 = [0.123, 2, 0.5]
    >>> M = compose_matrix(scale1, None, angle1, trans1, None)
    >>> scale2, shear2, angle2, trans2, persp2 = decompose_matrix(M)
    >>> allclose(scale1, scale2)
    True
    >>> allclose(angle1, angle2)
    True
    >>> allclose(trans1, trans2)
    True

    """
    M = [[1. if i == j else 0. for i in range(4)] for j in range(4)]
    if perspective is not None:
        P = matrix_from_perspective_entries(perspective)
        M = multiply_matrices(M, P)
    if translation is not None:
        T = matrix_from_translation(translation)
        M = multiply_matrices(M, T)
    if angles is not None:
        R = matrix_from_euler_angles(angles, static=True, axes="xyz")
        M = multiply_matrices(M, R)
    if shear is not None:
        Sh = matrix_from_shear_entries(shear)
        M = multiply_matrices(M, Sh)
    if scale is not None:
        Sc = matrix_from_scale_factors(scale)
        M = multiply_matrices(M, Sc)
    for i in range(4):
        for j in range(4):
            M[i][j] /= M[3][3]
    return M
Beispiel #2
0
    def concatenate(self, other):
        """Concatenate two transformations into one ``Transformation``.

        Note:
            Rz * Ry * Rx means that Rx is first transformation, Ry second, and
            Rz third.
        """
        cls = type(self)
        if not isinstance(other, cls):
            return Transformation(multiply_matrices(self.matrix, other.matrix))
        else:
            return cls(multiply_matrices(self.matrix, other.matrix))
 def concatenate(self, other):
     """Calculate dot product of two transformation matrices.
     
     Args:
         other (Transformation, Rotation,... list): The matrix to dot.
     """
     
     if type(other) == type([]): 
         if len(other) == 4 and len(other[0]) == 4: # concatenate with 4x4 transformation matrix
             return Transformation.from_matrix(multiply_matrices(self.matrix, other))
         else:
             raise Exception("The type %s is not supported to be multiplied by this class." % type(other))
     else: # concatenate with instances of Transformation, Rotation, Translation, etc.
         return Transformation.from_matrix(multiply_matrices(self.matrix, other.matrix))
Beispiel #4
0
    def change_basis(cls, frame_from, frame_to):
        """Computes a change of basis transformation between two frames.

        A basis change is essentially a remapping of geometry from one
        coordinate system to another.

        Args:
            frame_from (:class:`Frame`): a frame defining the original
                Cartesian coordinate system
            frame_to (:class:`Frame`): a frame defining the targeted
                Cartesian coordinate system

        Example:
            >>> from compas.geometry import Point, Frame
            >>> f1 = Frame([2, 2, 2], [0.12, 0.58, 0.81], [-0.80, 0.53, -0.26])
            >>> f2 = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
            >>> T = Transformation.change_basis(f1, f2)
            >>> p_f1 = Point(1, 1, 1) # point in f1
            >>> p_f1.transformed(T) # point represented in f2
            Point(1.395, 0.955, 1.934)
            >>> Frame.local_to_local_coords(f1, f2, p_f1)
            Point(1.395, 0.955, 1.934)
        """

        T1 = cls.from_frame(frame_from)
        T2 = cls.from_frame(frame_to)

        return cls(multiply_matrices(matrix_inverse(T2.matrix), T1.matrix))
Beispiel #5
0
    def from_frame_to_frame(cls, frame_from, frame_to):
        """Computes a transformation between two frames.

        This transformation allows to transform geometry from one Cartesian
        coordinate system defined by "frame_from" to another Cartesian
        coordinate system defined by "frame_to".

        Parameters
        ----------
        frame_from : :class:`Frame`
            A frame defining the original Cartesian coordinate system.
        frame_to : :class:`Frame`
            A frame defining the targeted Cartesian coordinate system.

        Returns
        -------
        Transformation
            The transformation representing a change of basis.

        Examples
        --------
        >>> from compas.geometry import Frame
        >>> f1 = Frame([2, 2, 2], [0.12, 0.58, 0.81], [-0.80, 0.53, -0.26])
        >>> f2 = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
        >>> T = Transformation.from_frame_to_frame(f1, f2)
        >>> f1.transform(T)
        >>> f1 == f2
        True

        """
        T1 = cls.from_frame(frame_from)
        T2 = cls.from_frame(frame_to)

        return cls(multiply_matrices(T2.matrix, matrix_inverse(T1.matrix)))
Beispiel #6
0
    def from_frame_to_frame(cls, frame_from, frame_to):
        """Computes a change of basis transformation between two frames.

        This transformation maps geometry from one Cartesian coordinate system
        defined by "frame_from" to the other Cartesian coordinate system
        defined by "frame_to".

        Args:
            frame_from (:class:`Frame`): a frame defining the original
                Cartesian coordinate system
            frame_to (:class:`Frame`): a frame defining the targeted
                Cartesian coordinate system

        Example:
            >>> from compas.geometry import Frame
            >>> f1 = Frame([2, 2, 2], [0.12, 0.58, 0.81], [-0.80, 0.53, -0.26])
            >>> f2 = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
            >>> T = Transformation.from_frame_to_frame(f1, f2)
            >>> f1.transform(T)
            >>> f1 == f2
            True
        """
        T1 = cls.from_frame(frame_from)
        T2 = cls.from_frame(frame_to)

        return cls(multiply_matrices(T2.matrix, inverse(T1.matrix)))
Beispiel #7
0
    def concatenated(self, other):
        """Concatenate two transformations into one ``Transformation``.

        Parameters
        ----------
        other: :class:`compas.geometry.Transformation`
            The transformation object to concatenate.

        Returns
        -------
        T: :class:`compas.geometry.Transformation`
            The new transformation that is the concatenation of this one and the other.

        Notes
        -----
        Rz * Ry * Rx means that Rx is first transformation, Ry second, and Rz third.
        """
        # T = self.copy()
        # T.concatenate(other)
        # return T
        cls = type(self)
        if isinstance(other, cls):
            return cls(multiply_matrices(self.matrix, other.matrix))
        return Transformation(multiply_matrices(self.matrix, other.matrix))
Beispiel #8
0
def transform_vectors(vectors, T):
    """Transform multiple vectors with one transformation matrix.

    Parameters
    ----------
    vectors : list of :class:`Vector` or list of list of float
        A list of vectors to be transformed.
    T : :class:`Transformation` list of list of float
        The transformation to apply.

    Examples
    --------
    >>> vectors = [[1, 0, 0], [1, 2, 4], [4, 7, 1]]
    >>> T = matrix_from_axis_and_angle([0, 2, 0], math.radians(45), point=[4, 5, 6])
    >>> vectors_transformed = transform_vectors(vectors, T)
    """
    return dehomogenize(multiply_matrices(homogenize(vectors, w=0.0), transpose_matrix(T)))
 def transform(self, xyz):
     """Transforms a point, vector, xyz coordinates or a list therefrom.
     
     Should this be split into transform_xyz_list and transform_xyz
     TODO: should be attached to the elements.
     """
     xyz = list(xyz)
                 
     if type(xyz[0]) == float or type(xyz[0]) == int: # point, vector, xyz coordinates
         point = xyz + [1.] # make homogeneous coordinates
         point = multiply_matrix_vector(self.matrix, point)
         return point[:3]
     else: # it is a list of xyz coordinates
         xyz = zip(*xyz) # transpose matrix
         xyz += [[1] * len(xyz[0])] # make homogeneous coordinates
         xyz = multiply_matrices(self.matrix, xyz)
         return zip(*xyz[:3]) # cutoff 1 and transpose again
Beispiel #10
0
    def concatenate(self, other):
        """Concatenate another transformation to this transformation.

        Parameters
        ----------
        other: :class:`compas.geometry.Transformation`
            The transformation object to concatenate.

        Returns
        -------
        None
            This transformation object is changed in-place.

        Notes
        -----
        Rz * Ry * Rx means that Rx is first transformation, Ry second, and Rz third.
        """
        self.matrix = multiply_matrices(self.matrix, other.matrix)
Beispiel #11
0
def transform_frames(frames, T):
    """Transform multiple frames with one transformation matrix.

    Parameters
    ----------
    frames : list of :class:`Frame`
        A list of frames to be transformed.
    T : :class:`Transformation`
        The transformation to apply on the frames.

    Examples
    --------
    >>> frames = [Frame([1, 0, 0], [1, 2, 4], [4, 7, 1]), Frame([0, 2, 0], [5, 2, 1], [0, 2, 1])]
    >>> T = matrix_from_axis_and_angle([0, 2, 0], math.radians(45), point=[4, 5, 6])
    >>> transformed_frames = transform_frames(frames, T)
    """
    points_and_vectors = homogenize_and_flatten_frames(frames)
    return dehomogenize_and_unflatten_frames(multiply_matrices(points_and_vectors, transpose_matrix(T)))
Beispiel #12
0
def matrix_change_basis(frame_from, frame_to):
    """Computes a change of basis transformation between two frames.

    A basis change is essentially a remapping of geometry from one
    coordinate system to another.

    Parameters
    ----------
    frame_from : :class:`Frame`
        A frame defining the original Cartesian coordinate system
    frame_to : :class:`Frame`
        A frame defining the targeted Cartesian coordinate system

    Example:
    >>> from compas.geometry import Point, Frame
    >>> f1 = Frame([2, 2, 2], [0.12, 0.58, 0.81], [-0.80, 0.53, -0.26])
    >>> f2 = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
    >>> T = matrix_change_basis(f1, f2)
    """
    T1 = matrix_from_frame(frame_from)
    T2 = matrix_from_frame(frame_to)
    return multiply_matrices(matrix_inverse(T2), T1)
Beispiel #13
0
def matrix_from_frame_to_frame(frame_from, frame_to):
    """Computes a transformation between two frames.

    This transformation allows to transform geometry from one Cartesian
    coordinate system defined by "frame_from" to another Cartesian
    coordinate system defined by "frame_to".

    Parameters
    ----------
    frame_from : :class:`Frame`
        A frame defining the original Cartesian coordinate system
    frame_to : :class:`Frame`
        A frame defining the targeted Cartesian coordinate system

    Examples
    --------
    >>> f1 = Frame([2, 2, 2], [0.12, 0.58, 0.81], [-0.80, 0.53, -0.26])
    >>> f2 = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
    >>> T = matrix_from_frame_to_frame(f1, f2)
    """
    T1 = matrix_from_frame(frame_from)
    T2 = matrix_from_frame(frame_to)
    return multiply_matrices(T2, matrix_inverse(T1))
Beispiel #14
0
def transform_vectors(vectors, T):
    return dehomogenize(
        multiply_matrices(homogenize(vectors, w=0.0), transpose_matrix(T)))
Beispiel #15
0
def transform_points(points, T):
    return dehomogenize(
        multiply_matrices(homogenize(points, w=1.0), transpose_matrix(T)))
Beispiel #16
0
def mesh_get_transformed_vertices(mesh, transformation_matrix):
    xyz = zip(*mesh.xyz)  # transpose matrix
    xyz += [[1] * len(xyz[0])]  # homogenize
    xyz = multiply_matrices(transformation_matrix, xyz)
    return zip(*xyz[:3])
Beispiel #17
0
def transform(points, T):
    points = homogenize(points)
    points = transpose_matrix(multiply_matrices(T, transpose_matrix(points)))
    return dehomogenize(points)
Beispiel #18
0
    f1 = Frame([2, 2, 2], [0.12, 0.58, 0.81], [-0.80, 0.53, -0.26])
    f2 = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
    T = Transformation.from_frame_to_frame(f1, f2)
    f1.transform(T)
    print(f1 == f2)

    f = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
    T = Transformation.from_frame(f)
    p = Point(0, 0, 0)
    p.transform(T)
    print(allclose(f.point, p))

    f1 = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
    T = Transformation.from_frame(f1)
    points = [[1.0, 1.0, 1.0], [1.68, 1.68, 1.27], [0.33, 1.73, 0.85]]
    points = transform_points(points, T)

    trans1 = [1, 2, 3]
    angle1 = [-2.142, 1.141, -0.142]
    scale1 = [0.123, 2, 0.5]
    T = matrix_from_translation(trans1)
    R = matrix_from_euler_angles(angle1)
    S = matrix_from_scale_factors(scale1)
    M = multiply_matrices(multiply_matrices(T, R), S)
    # M = compose_matrix(scale1, None, angle1, trans1, None)
    scale2, shear2, angle2, trans2, persp2 = decompose_matrix(M)
    print(allclose(scale1, scale2))
    print(allclose(angle1, angle2))
    print(allclose(trans1, trans2))