def get_distance(self, point): if not isinstance(point, Point): point = Point(*point) point.transform(self.inversetransform) x, y, z = point # Tetrahedron if self.type == 0: return (max(abs(x + y) - z, abs(x - y) + z) - self.radius) / self.sqrt3 # Octahedron elif self.type == 1: s = abs(x) + abs(y) + abs(z) return (s - self.radius) * self.tan30 # Dodecahedron elif self.type == 2: v = Vector((1+sqrt(5))/2, 1, 0) v.unitize() px = abs(x / self.radius) py = abs(y / self.radius) pz = abs(z / self.radius) p = Vector(px, py, pz) a = p.dot(v) b = p.dot(Vector(v.z, v.x, v.y)) c = p.dot(Vector(v.y, v.z, v.x)) q = (max(max(a, b), c) - v.x) * self.radius return q # Icosahedron elif self.type == 3: r = self.radius * 0.8506507174597755 v = Vector((sqrt(5) + 3)/2, 1, 0) v.unitize() w = sqrt(3)/3 px = abs(x / r) py = abs(y / r) pz = abs(z / r) p = Vector(px, py, pz) a = p.dot(v) b = p.dot(Vector(v.z, v.x, v.y)) c = p.dot(Vector(v.y, v.z, v.x)) d = p.dot([w,w,w]) - v.x q = max(max(max(a, b), c) - v.x, d) * r return q else: return 0
def get_distance(self, point): """ single point distance function """ if not isinstance(point, Point): point = Point(*point) distances = [(point.distance_to_point(p), p) for p in self.points] sortpoints = sorted(distances, key=lambda x: x[0]) closest = sortpoints[0][1] vc = Vector(*closest) d1 = vc.dot(vc) secondc = sortpoints[1][1] vs = Vector(*secondc) v1 = Vector(*point) - (vc + vs) / 2 v2 = vs - vc v2.unitize() d2 = v1.dot(v2) return abs(min(d1, d2)) - self.thickness / 2
front = Plane([0, -1, 0], [0, -1, 0]) back = Plane([0, +1, 0], [0, +1, 0]) halfspaces = array( [left.abcd, right.abcd, top.abcd, bottom.abcd, front.abcd, back.abcd], dtype=float) interior = array([0, 0, 0], dtype=float) hsi = HalfspaceIntersection(halfspaces, interior) hull = ConvexHull(hsi.intersections) mesh = Mesh.from_vertices_and_faces( [hsi.intersections[i] for i in hull.vertices], hull.simplices) mesh.unify_cycles() to_merge = [] for a, b in combinations(mesh.faces(), 2): na = Vector(*mesh.face_normal(a)) nb = Vector(*mesh.face_normal(b)) if na.dot(nb) >= 1: if na.cross(nb).length < 1e-6: to_merge.append([a, b]) for faces in to_merge: mesh.merge_faces(faces) viewer = App() viewer.add(mesh, show_vertices=True, pointsize=10) viewer.run()
from compas.geometry import Point from compas.geometry import Vector # Point p1 = Point(1, 2, 3) assert p1 ** 3 == [1, 8, 27] assert p1 + [0, 2, 1] == [1, 4, 4] # Vector u = Vector(1, 0, 0) v = Vector(0, 1, 0) assert u + v == [1, 1, 0] assert u.dot(v) == 0.0 assert u.cross(v) == [0, 0, 1] assert (u * 2).unitized() == [1, 0, 0]