Ejemplo n.º 1
0
def world_to_local_coords(frame, xyz):
    """Convert global coordinates to local coordinates.

    Parameters
    ----------
    frame : :class:`Frame` or [point, xaxis, yaxis]
        The local coordinate system.
    xyz : array-like
        The global coordinates of the points to convert.

    Returns
    -------
    list of list of float
        The coordinates of the given points in the local coordinate system.


    Examples
    --------
    >>> import numpy as np
    >>> f = Frame([0, 1, 0], [3, 4, 1], [1, 5, 9])
    >>> xyz = [Point(2, 3, 5)]
    >>> Point(*world_to_local_coords(f, xyz)[0])
    Point(3.726, 4.088, 1.550)
    """
    from compas.geometry.primitives import Frame
    T = matrix_change_basis(Frame.worldXY(), frame)
    return transform_points(xyz, T)
Ejemplo n.º 2
0
def local_to_world_coords(frame, xyz):
    """Convert local coordinates to global coordinates.

    Parameters
    ----------
    frame : :class:`Frame` or [point, xaxis, yaxis]
        The local coordinate system.
    xyz : list of `Points` or list of list of float
        The global coordinates of the points to convert.

    Returns
    -------
    list of list of float
        The coordinates of the given points in the local coordinate system.


    Examples
    --------
    >>> import numpy as np
    >>> f = Frame([0, 1, 0], [3, 4, 1], [1, 5, 9])
    >>> xyz = [Point(3.726, 4.088, 1.550)]
    >>> Point(*local_to_world_coords(f, xyz)[0])
    Point(2.000, 3.000, 5.000)
    """
    from compas.geometry.primitives import Frame  # noqa: F811
    T = matrix_change_basis(frame, Frame.worldXY())
    return transform_points(xyz, T)
Ejemplo n.º 3
0
    def to_vertices_and_faces(self, **kwargs):
        if 'u' in kwargs:
            u = kwargs['u']
        else:
            u = 10

        vertices = []
        a = 2 * pi / u
        for i in range(u):
            x = self.circle.radius * cos(i * a)
            y = self.circle.radius * sin(i * a)
            z = self.height / 2
            vertices.append([x, y, z])
            vertices.append([x, y, -z])

        # transform vertices to cylinder's plane
        frame = Frame.from_plane(self.circle.plane)
        M = matrix_from_frame(frame)
        vertices = transform_points(vertices, M)


        faces = []
        for i in range(0, u*2, 2):
            faces.append([i, i+1, (i+3)%(u*2), (i+2)%(u*2)])
        
        faces.append([i for i in range(0, u*2, 2)])
        faces.append([i for i in range(1, u*2, 2)])
        faces[-1].reverse()

        return vertices, faces
Ejemplo n.º 4
0
    def to_vertices_and_faces(self, **kwargs):
        """Returns a list of vertices and faces, called by `Mesh.from_shape()`."""
        if 'u' in kwargs:
            u = kwargs['u']
        else:
            u = 10

        vertices = []
        a = 2 * pi / u
        for i in range(u):
            x = self.circle.radius * cos(i * a)
            y = self.circle.radius * sin(i * a)
            vertices.append([x, y, 0])
        vertices.append([0, 0, self.height])

        # transform vertices to cylinder's plane
        frame = Frame.from_plane(self.circle.plane)
        M = matrix_from_frame(frame)
        vertices = transform_points(vertices, M)

        faces = []
        last = len(vertices) - 1
        for i in range(u):
            faces.append([i, (i + 1) % u, last])
        faces.append([i for i in range(u)])
        faces[-1].reverse()

        return vertices, faces
Ejemplo n.º 5
0
    def to_vertices_and_faces(self, **kwargs):
        """Returns a list of vertices and faces"""

        u = kwargs.get('u') or 10
        if u < 3:
            raise ValueError('The value for u should be u > 3.')

        vertices = []
        a = 2 * pi / u
        for i in range(u):
            x = self.circle.radius * cos(i * a)
            y = self.circle.radius * sin(i * a)
            z = self.height / 2
            vertices.append([x, y, z])
            vertices.append([x, y, -z])

        # transform vertices to cylinder's plane
        frame = Frame.from_plane(self.circle.plane)
        M = matrix_from_frame(frame)
        vertices = transform_points(vertices, M)

        faces = []
        for i in range(0, u * 2, 2):
            faces.append([i, i + 1, (i + 3) % (u * 2), (i + 2) % (u * 2)])

        faces.append([i for i in range(0, u * 2, 2)])
        faces.append([i for i in range(1, u * 2, 2)])
        faces[-1].reverse()

        return vertices, faces
Ejemplo n.º 6
0
def test_basis_vectors_from_matrix():
    f = Frame([0, 0, 0], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
    R = matrix_from_frame(f)
    xaxis, yaxis = basis_vectors_from_matrix(R)
    assert np.allclose(
        xaxis, [0.6807833515407016, 0.6807833515407016, 0.2703110366411609])
    assert np.allclose(
        yaxis, [-0.6687681911461376, 0.7282315441900513, -0.14975955581430114])
Ejemplo n.º 7
0
def test_matrix_from_frame():
    f = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
    T = matrix_from_frame(f)
    t = [[0.6807833515407016, -0.6687681911461376, -0.29880283595731283, 1.0],
         [0.6807833515407016, 0.7282315441900513, -0.0788216106888398, 1.0],
         [0.2703110366411609, -0.14975955581430114, 0.9510541619236438, 1.0],
         [0.0, 0.0, 0.0, 1.0]]
    assert np.allclose(T, t)
Ejemplo n.º 8
0
def test_reflection_from_frame():
    point = [1, 1, 1]
    x = [1, 0, 0]
    y = [0, 1, 0]

    f = Frame(point, x, y)
    R1 = Reflection.from_frame(f)
    R2 = Transformation.from_matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1, 2],
                                     [0, 0, 0, 1]])
    assert R1 == R2
Ejemplo n.º 9
0
 def from_bounding_box(cls, bbox):
     a = bbox[0]
     b = bbox[1]
     d = bbox[3]
     e = bbox[4]
     xaxis = Vector(*subtract_vectors(d, a))
     yaxis = Vector(*subtract_vectors(b, a))
     zaxis = Vector(*subtract_vectors(e, a))
     xsize = xaxis.length
     ysize = yaxis.length
     zsize = zaxis.length
     frame = Frame(a, xaxis, yaxis)
     return cls(frame, xsize, ysize, zsize)
Ejemplo n.º 10
0
 def from_bounding_box(cls, bbox):
     # this should put the frame at the centroid of the box
     # not at the bottom left corner
     a = bbox[0]
     b = bbox[1]
     d = bbox[3]
     e = bbox[4]
     xaxis = Vector(*subtract_vectors(d, a))
     yaxis = Vector(*subtract_vectors(b, a))
     zaxis = Vector(*subtract_vectors(e, a))
     xsize = xaxis.length
     ysize = yaxis.length
     zsize = zaxis.length
     frame = Frame(a, xaxis, yaxis)
     frame.point += frame.xaxis * 0.5 * xsize + frame.yaxis * 0.5 * ysize + frame.zaxis * 0.5 * zsize
     return cls(frame, xsize, ysize, zsize)
Ejemplo n.º 11
0
    def from_width_height_depth(cls, width, height, depth):
        """Construct a box from its width, height and depth.

        Parameters
        ----------
        width : float
            Width of the box.
        height : float
            Height of the box.
        depth : float
            Depth of the box.

        Returns
        -------
        Box
            The resulting box.

        Notes
        -----
        The bottom left corner of the box is positioned at the origin of the
        coordinates system. The box is axis-aligned.

        Examples
        --------
        >>> from compas.geometry import Box
        >>> box = Box.from_width_height_depth(1.0, 2.0, 3.0)

        """
        width = float(width)
        height = float(height)
        depth = float(depth)

        if width == 0.0:
            raise Exception('Width cannot be zero.')

        if height == 0.0:
            raise Exception('Height cannot be zero.')

        if depth == 0.0:
            raise Exception('Depth cannot be zero.')

        return cls(Frame.worldXY(), width, depth, height)
Ejemplo n.º 12
0
    def from_corner_corner_height(cls, corner1, corner2, height):
        """Construct a box from the opposite corners of its base and its height.

        Parameters
        ----------
        corner1 : point
            The XYZ coordinates of the bottom left corner of the base of the box.
        corner2 : point
            The XYZ coordinates of the top right corner of the base of the box.
        height : float
            The height of the box.

        Returns
        -------
        Box
            The resulting box.

        Examples
        --------
        >>> box = Box.from_corner_corner_height([0.0, 0.0, 0.0], [1.0, 1.0, 0.0], 1.0)

        """
        # this should put the frame at the centroid of the box
        # not at the bottom left corner
        if height == 0:
            raise Exception('The box should have a height.')

        x1, y1, z1 = corner1
        x2, y2, z2 = corner2

        xaxis = Vector(x2 - x1, 0, 0)
        yaxis = Vector(0, y2 - y1, 0)
        width = xaxis.length
        depth = yaxis.length

        if z1 != z2:
            raise Exception('Corners should be in the same horizontal plane.')

        frame = Frame(corner1, xaxis, yaxis)
        frame.point += frame.xaxis * 0.5 * width + frame.yaxis * 0.5 * depth + frame.zaxis * 0.5 * height
        return cls(frame, width, depth, height)
Ejemplo n.º 13
0
    def from_data(cls, data):
        """Construct a box from its data representation.

        Parameters
        ----------
        data : :obj:`dict`
            The data dictionary.

        Returns
        -------
        Box
            The constructed box.

        Examples
        --------
        >>> data = {'frame': Frame.worldXY().data, 'xsize': 1.0, 'ysize': 1.0, 'zsize': 1.0}
        >>> box = Box.from_data(data)

        """
        box = cls(Frame.worldXY(), 1, 1, 1)
        box.data = data
        return box
Ejemplo n.º 14
0
    def from_diagonal(cls, diagonal):
        """Construct a box from its main diagonal.

        Parameters
        ----------
        diagonal : segment
            The diagonal of the box, represented by a pair of points in space.

        Returns
        -------
        Box
            The resulting box.

        Examples
        --------
        >>> diagonal = [0.0, 0.0, 0.0], [1.0, 1.0, 1.0]
        >>> box = Box.from_diagonal(diagonal)

        """
        # this should put the frame at the centroid of the box
        # not at the bottom left corner
        d1, d2 = diagonal

        x1, y1, z1 = d1
        x2, y2, z2 = d2

        if z1 == z2:
            raise Exception('The box has no height.')

        xaxis = Vector(x2 - x1, 0, 0)
        yaxis = Vector(0, y2 - y1, 0)
        zaxis = Vector(0, 0, z2 - z1)
        width = xaxis.length
        depth = yaxis.length
        height = zaxis.length

        frame = Frame(d1, xaxis, yaxis)
        frame.point += frame.xaxis * 0.5 * width + frame.yaxis * 0.5 * depth + frame.zaxis * 0.5 * height
        return cls(frame, width, depth, height)
Ejemplo n.º 15
0
    def to_vertices_and_faces(self, **kwargs):
        """Returns a list of vertices and faces"""

        u = kwargs.get('u') or 10
        v = kwargs.get('v') or 10
        if u < 3:
            raise ValueError('The value for u should be u > 3.')
        if v < 3:
            raise ValueError('The value for v should be v > 3.')

        theta = pi * 2 / u
        phi = pi * 2 / v
        vertices = []
        for i in range(u):
            for j in range(v):
                x = cos(i * theta) * (self.radius_axis +
                                      self.radius_pipe * cos(j * phi))
                y = sin(i * theta) * (self.radius_axis +
                                      self.radius_pipe * cos(j * phi))
                z = self.radius_pipe * sin(j * phi)
                vertices.append([x, y, z])

        # transform vertices to torus' plane
        frame = Frame.from_plane(self.plane)
        M = matrix_from_frame(frame)
        vertices = transform_points(vertices, M)

        faces = []
        for i in range(u):
            ii = (i + 1) % u
            for j in range(v):
                jj = (j + 1) % v
                a = i * v + j
                b = ii * v + j
                c = ii * v + jj
                d = i * v + jj
                faces.append([a, b, c, d])
        return vertices, faces
Ejemplo n.º 16
0
    def from_diagonal(cls, diagonal):
        """Construct a box from its main diagonal.

        Parameters
        ----------
        diagonal : segment
            The diagonal of the box, represented by a pair of points in space.

        Returns
        -------
        Box
            The resulting box.

        Examples
        --------
        >>> from compas.geometry import Box
        >>> diagonal = [0.0, 0.0, 0.0], [1.0, 1.0, 1.0]
        >>> box = Box.from_diagonal(diagonal)

        """
        d1, d2 = diagonal

        x1, y1, z1 = d1
        x2, y2, z2 = d2

        if z1 == z2:
            raise Exception('The box has no height.')

        xaxis = Vector(x2 - x1, 0, 0)
        yaxis = Vector(0, y2 - y1, 0)
        zaxis = Vector(0, 0, z2 - z1)
        width = xaxis.length
        depth = yaxis.length
        height = zaxis.length

        frame = Frame(d1, xaxis, yaxis)
        return cls(frame, width, depth, height)
Ejemplo n.º 17
0
    def to_vertices_and_faces(self, **kwargs):
        """Returns a list of vertices and faces, called by `Mesh.from_shape()`."""
        if 'u' in kwargs:
            u = kwargs['u']
        else:
            u = 10
        if 'v' in kwargs:
            v = kwargs['v']
        else:
            v = 10

        theta = pi*2 / u
        phi = pi*2 / v
        vertices = []
        for i in range(u):
            for j in range(v):
                x = cos(i * theta) * (self.radius_axis + self.radius_pipe * cos(j * phi))
                y = sin(i * theta) * (self.radius_axis + self.radius_pipe * cos(j * phi))
                z = self.radius_pipe * sin(j * phi)
                vertices.append([x, y, z])
        
        # transform vertices to torus' plane
        frame = Frame.from_plane(self.plane)
        M = matrix_from_frame(frame)
        vertices = transform_points(vertices, M)

        faces = []
        for i in range(u):
            ii = (i + 1) % u
            for j in range(v):
                jj = (j + 1) % v
                a = i * v + j
                b = ii * v + j
                c = ii * v + jj
                d = i * v + jj
                faces.append([a, b, c, d])
        return vertices, faces
Ejemplo n.º 18
0
    def to_vertices_and_faces(self, **kwargs):
        """Returns a list of vertices and faces"""

        u = kwargs.get('u') or 10
        if u < 3:
            raise ValueError('The value for u should be u > 3.')

        vertices = []
        a = 2 * pi / u
        z = self.height / 2
        for i in range(u):
            x = self.circle.radius * cos(i * a)
            y = self.circle.radius * sin(i * a)
            vertices.append([x, y, z])
            vertices.append([x, y, -z])
        # add v in bottom and top's circle center
        vertices.append([0, 0, z])
        vertices.append([0, 0, -z])

        # transform vertices to cylinder's plane
        frame = Frame.from_plane(self.circle.plane)
        M = matrix_from_frame(frame)
        vertices = transform_points(vertices, M)

        faces = []
        # side faces
        for i in range(0, u * 2, 2):
            faces.append([i, i + 1, (i + 3) % (u * 2), (i + 2) % (u * 2)])
        # top and bottom circle faces
        for i in range(0, u * 2, 2):
            top = [i, (i + 2) % (u * 2), len(vertices) - 2]
            bottom = [i + 1, (i + 3) % (u * 2), len(vertices) - 1]
            faces.append(top)
            faces.append(bottom[::-1])

        return vertices, faces
Ejemplo n.º 19
0
        >>> T = Transformation.from_frame(frame)
        >>> circle_transformed = cylinder.transformed(T)

        """
        cylinder = self.copy()
        cylinder.transform(transformation)
        return cylinder


# ==============================================================================
# Main
# ==============================================================================

if __name__ == "__main__":
    from compas.geometry import Transformation

    cylinder = Cylinder(Circle(Plane.worldXY(), 5), 7)
    frame = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
    print(frame.normal)
    T = Transformation.from_frame(frame)
    cylinder.transform(T)
    print(cylinder)

    print(Plane.worldXY().data)
    data = {'circle': Circle(Plane.worldXY(), 5).data, 'height': 7.}
    cylinder = Cylinder.from_data(data)
    print(cylinder)

    import doctest
    doctest.testmod()
Ejemplo n.º 20
0
 def frame(self, frame):
     self._frame = Frame(frame[0], frame[1], frame[2])
Ejemplo n.º 21
0
 def data(self, data):
     self.frame = Frame.from_data(data['frame'])
     self.xsize = data['xsize']
     self.ysize = data['ysize']
     self.zsize = data['zsize']
Ejemplo n.º 22
0
def test_inverse():
    f = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
    T = Transformation.from_frame(f)
    assert Transformation() == T * T.inverse()
Ejemplo n.º 23
0
        >>> torus = Torus(Plane.worldXY(), 5, 2)
        >>> frame = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
        >>> T = Transformation.from_frame(frame)
        >>> torus_transformed = torus.transformed(T)

        """
        torus = self.copy()
        torus.transform(transformation)
        return torus


if __name__ == '__main__':
    from compas.geometry import Frame
    from compas.geometry import Plane
    from compas.geometry import Transformation

    torus = Torus(Plane.worldXY(), 5, 2)
    frame = Frame([5, 0, 0], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
    T = Transformation.from_frame(frame)
    torus.transform(T)
    print(torus)

    torus = Torus(Plane.worldXY(), 5, 2)
    print(torus.data)
    print(torus)
    torus = Torus.from_data(torus.data)
    print(torus)

    import doctest
    doctest.testmod()
Ejemplo n.º 24
0
def test_from_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)
    assert f1 == f2