def __init__(self, radius, type=0, frame=None): self.radius = radius self.type = type self.frame = frame or Frame.worldXY() self.inversetransform = matrix_inverse(matrix_from_frame(self.frame)) self.sqrt3 = sqrt(3) self.tan30 = tan(pi/6)
def __init__(self, radiusA=3, radiusB=4, k=0.1, frame=Frame.worldXY()): self.ra = radiusA self.rb = radiusB self.k = k self.frame = frame self.matrix = matrix_from_frame(self.frame) self.inversedmatrix = matrix_inverse(self.matrix)
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
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
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
def __init__(self, radiusX=3, radiusY=2, radiusZ=1, frame=Frame.worldXY()): self.radiusX = radiusX self.radiusY = radiusY self.radiusZ = radiusZ self.frame = frame transform = matrix_from_frame(self.frame) self.inversetransform = matrix_inverse(transform)
def frame_to_vrep_pose(frame, scale): # compas_fab uses meters, just like V-REP, # so in general, scale should always be 1 pose = matrix_from_frame(frame) pose[0][3] = pose[0][3] / scale pose[1][3] = pose[1][3] / scale pose[2][3] = pose[2][3] / scale return pose[0] + pose[1] + pose[2] + pose[3]
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 allclose(T, t)
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 allclose( xaxis, [0.6807833515407016, 0.6807833515407016, 0.2703110366411609]) assert allclose( yaxis, [-0.6687681911461376, 0.7282315441900513, -0.14975955581430114])
def to_vertices_and_faces(self, u=16, triangulated=False): """Returns a list of vertices and faces. Parameters ---------- u : int, optional Number of faces in the "u" direction. triangulated: bool, optional Flag indicating that the faces have to be triangulated. Returns ------- (vertices, faces) A list of vertex locations and a list of faces, with each face defined as a list of indices into the list of vertices. """ 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]) if triangulated: triangles = [] for face in faces: if len(face) == 4: triangles.append(face[0:3]) triangles.append([face[0], face[2], face[3]]) else: triangles.append(face) faces = triangles return vertices, faces
def to_vertices_and_faces(self, u=16, triangulated=False): """Returns a list of vertices and faces. Parameters ---------- u : int, optional Number of faces in the "u" direction. triangulated: bool, optional If True, triangulate the faces. Returns ------- list[list[float]] A list of vertex locations. list[list[int]] And a list of faces, with each face defined as a list of indices into the list of vertices. """ if u < 3: raise ValueError('The value for u should be u > 3.') vertices = [[0, 0, 0]] a = 2 * pi / u radius = self.circle.radius for i in range(u): x = radius * cos(i * a) y = radius * sin(i * a) vertices.append([x, y, 0]) vertices.append([0, 0, self.height]) frame = Frame.from_plane(self.circle.plane) M = matrix_from_frame(frame) vertices = transform_points(vertices, M) faces = [] first = 0 last = len(vertices) - 1 for i, j in pairwise(range(1, last)): faces.append([i, j, last]) faces.append([j, i, first]) faces.append([last - 1, 1, last]) faces.append([1, last - 1, first]) if triangulated: triangles = [] for face in faces: if len(face) == 4: triangles.append(face[0:3]) triangles.append([face[0], face[2], face[3]]) else: triangles.append(face) faces = triangles return vertices, faces
def __init__(self, ltype=0, unitcell=1.0, thickness=0.1, polarnumber=6, frame=Frame.worldXY()): self.pointlist = self.create_points() self.ltypes = self.create_types() self._ltype = None self.ltype = ltype self.unitcell = unitcell self.thickness = thickness self.polarnumber = polarnumber self._frame = None self.frame = frame transform = matrix_from_frame(self.frame) self.inversetransform = matrix_inverse(transform)
def to_vertices_and_faces(self, u=10, v=10): """Returns a list of vertices and faces Parameters ---------- u : int, optional Number of faces in the "u" direction. Default is ``10``. v : int, optional Number of faces in the "v" direction. Default is ``10``. Returns ------- (vertices, faces) A list of vertex locations and a list of faces, with each face defined as a list of indices into the list of vertices. """ 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
def get_distance(self, point): if not isinstance(point, Point): point = Point(*point) m = matrix_from_frame(self.frame) mi = matrix_inverse(m) point.transform(mi) tp = Point(point[0], point[1], 0) cp = closest_point_on_polyline_xy(tp, self.polyline) d = tp.distance_to_point(cp) if is_point_in_polygon_xy(tp, self.polyline): d = -1. * d d = max(d, abs(point.z) - self.height / 2.0) return d
def to_vertices_and_faces(self, u=10): """Returns a list of vertices and faces. Parameters ---------- u : int, optional Number of faces in the "u" direction. Default is ``10``. Returns ------- (vertices, faces) A list of vertex locations and a list of faces, with each face defined as a list of indices into the list of vertices. """ 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
def get_distance(self, point): """ single point distance function """ if not isinstance(point, Point): point = Point(*point) frame = Frame.from_plane(self.cone.plane) m = matrix_from_frame(frame) mi = matrix_inverse(m) point.transform(mi) dxy = length_vector_xy(point) a = 1.1 c = [sin(a), cos(a)] # dot product d = sum( [i * j for (i, j) in zip(c, [dxy, point.z - self.cone.height])]) return d
def to_vertices_and_faces(self, u=10): """Returns a list of vertices and faces. Parameters ---------- u : int, optional Number of faces in the "u" direction. Default is ``10``. Returns ------- (vertices, faces) A list of vertex locations and a list of faces, with each face defined as a list of indices into the list of vertices. """ if u < 3: raise ValueError('The value for u should be u > 3.') vertices = [[0, 0, 0]] 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]) frame = Frame.from_plane(self.circle.plane) M = matrix_from_frame(frame) vertices = transform_points(vertices, M) faces = [] first = 0 last = len(vertices) - 1 for i, j in pairwise(range(1, last)): faces.append([i, j, last]) faces.append([j, i, first]) faces.append([last - 1, 1, last]) faces.append([1, last - 1, first]) return vertices, faces
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
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
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
def box(self, box): if not isinstance(box, Box): raise ValueError self._box = box transform = matrix_from_frame(self.box.frame) self.inversetransform = matrix_inverse(transform)
def __init__(self, size=3.0, frame=None): self.size = size self.frame = frame or Frame.worldXY() self.inversetransform = matrix_inverse(matrix_from_frame(self.frame))
def __init__(self, torus): self.torus = torus frame = Frame.from_plane(self.torus.plane) transform = matrix_from_frame(frame) self.inversetransform = matrix_inverse(transform)
def __init__(self, polyline, height=1.0, frame=None): self.polyline = polyline self.height = height self.frame = frame or Frame.worldXY() self.inversetransform = matrix_inverse(matrix_from_frame(self.frame))
def to_vertices_and_faces(self, u=10, v=10): """Returns a list of vertices and faces. Parameters ---------- u : int, optional Number of faces in the "u" direction. Default is ``10``. v : int, optional Number of faces in the "v" direction. Default is ``10``. Returns ------- (vertices, faces) A list of vertex locations and a list of faces, with each face defined as a list of indices into the list of vertices. """ 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.') if v % 2 == 1: v += 1 theta = pi / v phi = pi * 2 / u hpi = pi * 0.5 halfheight = self.line.length / 2 sidemult = -1 capswitch = 0 vertices = [] for i in range(1, v + 1): for j in range(u): a = i + capswitch tx = self.radius * cos(a * theta - hpi) * cos(j * phi) ty = self.radius * cos(a * theta - hpi) * sin(j * phi) tz = self.radius * sin(a * theta - hpi) + sidemult * halfheight vertices.append([tx, ty, tz]) # switch from lower pole cap to upper pole cap if i == v / 2 and sidemult == -1: capswitch = -1 sidemult *= -1 vertices.append([0, 0, halfheight + self.radius]) vertices.append([0, 0, -halfheight - self.radius]) # move points to correct location in space plane = Plane(self.line.midpoint, self.line.direction) frame = Frame.from_plane(plane) M = matrix_from_frame(frame) vertices = transform_points(vertices, M) faces = [] # south pole triangle fan sp = len(vertices) - 1 for j in range(u): faces.append([sp, (j + 1) % u, j]) for i in range(v - 1): for j in range(u): jj = (j + 1) % u a = i * u + j b = i * u + jj c = (i + 1) * u + jj d = (i + 1) * u + j faces.append([a, b, c, d]) # north pole triangle fan np = len(vertices) - 2 for j in range(u): nc = len(vertices) - 3 - j nn = len(vertices) - 3 - (j + 1) % u faces.append([np, nn, nc]) return vertices, faces
def __init__(self, cone): self.cone = cone self.frame = Frame.from_plane(self.cone.plane) self.matrix = matrix_from_frame(self.frame) self.inversedmatrix = matrix_inverse(self.matrix)
def __init__(self, cylinder): self.cylinder = cylinder frame = Frame.from_plane(self.cylinder.plane) transform = matrix_from_frame(frame) self.inversetransform = matrix_inverse(transform)
def to_vertices_and_faces(self, u=16, v=16, triangulated=False): """Returns a list of vertices and faces Parameters ---------- u : int, optional Number of faces in the "u" direction. v : int, optional Number of faces in the "v" direction. triangulated: bool, optional If True, triangulate the faces. Returns ------- list[list[float]] A list of vertex locations. list[list[int]] And a list of faces, with each face defined as a list of indices into the list of vertices. """ 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]) if triangulated: triangles = [] for face in faces: if len(face) == 4: triangles.append(face[0:3]) triangles.append([face[0], face[2], face[3]]) else: triangles.append(face) faces = triangles return vertices, faces
def __init__(self, distobj=None, frame=Frame.worldXY()): self.distobj = distobj self.frame = frame transform = matrix_from_frame(self.frame) self.inversetransform = matrix_inverse(transform)