def quinto(poly: polyhedron) -> polyhedron: flag = polyflag() for i, f in enumerate(poly.faces): lv = list(map(lambda i: poly.vertices[i], f)) centroid = calc_centroid(lv) v1, v2 = f[-2:] for v3 in f: midpt = midpoint(poly.vertices[v1], poly.vertices[v2]) innerpt = midpoint(midpt, centroid) flag.newV(midName(v1, v2), midpt) flag.newV(f'inner_{i}_{midName(v1, v2)}', innerpt) flag.newV(f'{v2}', poly.vertices[v2]) flag.newFlag(f'f{i}_{v2}', f'inner_{i}_{midName(v1, v2)}', midName(v1, v2)) flag.newFlag(f'f{i}_{v2}', midName(v1, v2), f'{v2}') flag.newFlag(f'f{i}_{v2}', f'{v2}', midName(v2, v3)) flag.newFlag(f'f{i}_{v2}', midName(v2, v3), f'inner_{i}_{midName(v2, v3)}') flag.newFlag(f'f{i}_{v2}', f'inner_{i}_{midName(v2, v3)}', f'inner_{i}_{midName(v1, v2)}') # inner rotated face of same vertex-number as original flag.newFlag(f'f_in_{i}', f'inner_{i}_{midName(v1, v2)}', f'inner_{i}_{midName(v2, v3)}') # shift over one v1, v2 = v2, v3 newpoly = flag.topoly() newpoly.name = f'q{poly.name}' return newpoly
def gyro(poly: polyhedron) -> polyhedron: flag = polyflag() for i, v in enumerate( poly.vertices): # each old vertex is a new vertex flag.newV(f'v{i}', unit(v)) for i, f in enumerate(poly.faces): flag.newV(f'center{i}', unit(poly.centersArray[i])) for i, f in enumerate(poly.faces): v1, v2 = f[-2:] for j, v in enumerate(f): v3 = v flag.newV(f'{v1}~{v2}', oneThird(poly.vertices[v1], poly.vertices[v2])) # new v in face fname = f'{i}f{v1}' flag.newFlag(fname, f'center{i}', f'{v1}~{v2}') # five new flags flag.newFlag(fname, f'{v1}~{v2}', f'{v2}~{v1}') flag.newFlag(fname, f'{v2}~{v1}', f'v{v2}') flag.newFlag(fname, f'v{v2}', f'{v2}~{v3}') flag.newFlag(fname, f'{v2}~{v3}', f'center{i}') v1, v2 = v2, v3 newpoly = flag.topoly() newpoly.name = f'g{poly.name}' return newpoly
def chamfer(poly: polyhedron, dist=0.5) -> polyhedron: normals = poly.normals # [calc_normal([poly.vertices[ic] for ic in f]) for f in poly.faces] flag = polyflag() for i, f in enumerate( poly.faces): # For each face f in the original poly v1 = f[-1] v1new = f'{i}_{v1}' for v2 in f: flag.newV(v2, mult(1.0 + dist, poly.vertices[v2])) v2new = f'{i}_{v2}' flag.newV(v2new, add(poly.vertices[v2], mult(dist * 1.5, normals[i]))) flag.newFlag(f'orig{i}', v1new, v2new) facename = f'hex{v1}_{v2}' if v1 < v2 else f'hex{v2}_{v1}' flag.newFlag(facename, v2, v2new) flag.newFlag(facename, v2new, v1new) flag.newFlag(facename, v1new, v1) v1 = v2 v1new = v2new newpoly = flag.topoly() newpoly.name = f'c{poly.name}' return newpoly
def dual(poly: polyhedron) -> polyhedron: flag = polyflag() face = [{} for _ in range(len(poly.vertices))] for i, f in enumerate(poly.faces): v1 = f[-1] for v2 in f: face[v1][f'v{v2}'] = f'{i}' v1 = v2 centers = poly.centers for i, _ in enumerate(poly.faces): flag.newV(f'{i}', centers[i]) for i, f in enumerate(poly.faces): v1 = f[-1] for v2 in f: flag.newFlag(v1, face[v2][f'v{v1}'], f'{i}') v1 = v2 dpoly = flag.topoly() # build topological dual from flags # match F index ordering to V index ordering on dual sortF = [[] for _ in range(len(dpoly.faces))] for f in dpoly.faces: k = intersect(poly.faces[f[0]], poly.faces[f[1]], poly.faces[f[2]]) sortF[k] = f dpoly.faces = sortF if poly.name[0] != 'd': dpoly.name = f'd{poly.name}' else: dpoly.name = poly.name[1:] return dpoly
def propellor(poly: polyhedron) -> polyhedron: flag = polyflag() for i, v in enumerate( poly.vertices): # each old vertex is a new vertex flag.newV(f'v{i}', unit(v)) for i, f in enumerate(poly.faces): v1, v2 = f[-2:] for v in f: v3 = v flag.newV( f'{v1}~{v2}', oneThird( poly.vertices[v1], poly.vertices[v2])) # new v in face, 1/3rd along edge fname = f'{i}f{v2}' flag.newFlag(f'v{i}', f'{v1}~{v2}', f'{v2}~{v3}') # five new flags flag.newFlag(fname, f'{v1}~{v2}', f'{v2}~{v1}') flag.newFlag(fname, f'{v2}~{v1}', f'v{v2}') flag.newFlag(fname, f'v{v2}', f'{v2}~{v3}') flag.newFlag(fname, f'{v2}~{v3}', f'{v1}~{v2}') v1, v2 = v2, v3 newpoly = flag.topoly() newpoly.name = f'p{poly.name}' return newpoly
def hollow(poly: polyhedron, inset_dist=0.5, thickness=0.2) -> polyhedron: dualnormals = transform.dual(poly).calc_normals() normals = poly.normals # poly.calc_normals() centers = poly.centers # poly.calc_centers() flag = polyflag() for i, p in enumerate(poly.vertices): flag.newV(f'v{i}', p) flag.newV(f'downv{i}', add(p, mult(-1 * thickness, dualnormals[i]))) for i, f in enumerate(poly.faces): for v in f: flag.newV(f'fin{i}v{v}', tween(poly.vertices[v], centers[i], inset_dist)) flag.newV( f'findown{i}v{v}', add(tween(poly.vertices[v], centers[i], inset_dist), mult(-1 * thickness, normals[i]))) for i, f in enumerate(poly.faces): v1 = f'v{f[-1]}' for v in f: v2 = f'v{v}' fname = f'{i}{v1}' flag.newFlag(fname, v1, v2) flag.newFlag(fname, v2, f'fin{i}{v2}') flag.newFlag(fname, f'fin{i}{v2}', f'fin{i}{v1}') flag.newFlag(fname, f'fin{i}{v1}', v1) fname = f'sides{i}{v1}' flag.newFlag(fname, f'fin{i}{v1}', f'fin{i}{v2}') flag.newFlag(fname, f'fin{i}{v2}', f'findown{i}{v2}') flag.newFlag(fname, f'findown{i}{v2}', f'findown{i}{v1}') flag.newFlag(fname, f'findown{i}{v1}', f'fin{i}{v1}') fname = f'bottom{i}{v1}' flag.newFlag(fname, f'down{v2}', f'down{v1}') flag.newFlag(fname, f'down{v1}', f'findown{i}{v1}') flag.newFlag(fname, f'findown{i}{v1}', f'findown{i}{v2}') flag.newFlag(fname, f'findown{i}{v2}', f'down{v2}') v1 = v2 newpoly = flag.topoly() newpoly.name = f'H{poly.name}' return newpoly
def ambo(poly: polyhedron) -> polyhedron: flag = polyflag() for i, f in enumerate(poly.faces): v1, v2 = f[-2:] for v3 in f: if v1 < v2: # vertices are the midpoints of all edges of original poly flag.newV(midName(v1, v2), midpoint(poly.vertices[v1], poly.vertices[v2])) # two new flags: One whose face corresponds to the original f: flag.newFlag(f'orig{i}', midName(v1, v2), midName(v2, v3)) # Another flag whose face corresponds to (the truncated) v2: flag.newFlag(f'dual{v2}', midName(v2, v3), midName(v1, v2)) # shift over one v1, v2 = v2, v3 newpoly = flag.topoly() newpoly.name = f'a{poly.name}' return newpoly
def insetN(poly: polyhedron, n=0, inset_dist=0.5, popout_dist=-0.2) -> polyhedron: flag = polyflag() for i, p in enumerate(poly.vertices): flag.newV(f'v{i}', p) normals = poly.normals # poly.calc_normals() centers = poly.centers # poly.calc_centers() for i, f in enumerate(poly.faces): if len(f) == n or n == 0: for v in f: flag.newV( f'f{i}v{v}', add(tween(poly.vertices[v], centers[i], inset_dist), mult(popout_dist, normals[i]))) foundAny = False for i, f in enumerate(poly.faces): v1 = f'v{f[-1]}' for v in f: v2 = f'v{v}' if len(f) == n or n == 0: foundAny = True fname = f'{i}{v1}' flag.newFlag(fname, v1, v2) flag.newFlag(fname, v2, f'f{i}{v2}') flag.newFlag(fname, f'f{i}{v2}', f'f{i}{v1}') flag.newFlag(fname, f'f{i}{v1}', v1) # new inset, extruded face flag.newFlag(f'ex{i}', f'f{i}{v1}', f'f{i}{v2}') else: flag.newFlag(i, v1, v2) # same old flag, if non-n v1 = v2 if not foundAny: print(f'No {n}-fold components were found.') newpoly = flag.topoly() newpoly.name = f'n{"" if n==0 else n}{poly.name}' return newpoly
def perspectiva1(poly: polyhedron) -> polyhedron: centers = poly.calc_centers() flag = polyflag() for i, p in enumerate(poly.vertices): flag.newV(f'v{i}', p) for i, f in enumerate(poly.faces): v1 = f'v{f[-2]}' v2 = f'v{f[-1]}' vert1 = poly.vertices[f[-2]] vert2 = poly.vertices[f[-1]] for v in f: v3 = f'v{v}' vert3 = poly.vertices[v] v12 = f'{v1}~{v2}' # names for "oriented" midpoint v21 = f'{v2}~{v1}' v23 = f'{v2}~{v3}' # on each Nface, N new points inset from edge midpoints towards center = "stellated" points flag.newV(v12, midpoint(midpoint(vert1, vert2), centers[i])) flag.newFlag(f'in{i}', v12, v23) # new tri face constituting the remainder of the stellated Nface flag.newFlag(f'f{i}{v2}', v23, v12) flag.newFlag(f'f{i}{v2}', v12, v2) flag.newFlag(f'f{i}{v2}', v2, v23) # one of the two new triangles replacing old edge between v1->v2 flag.newFlag(f'f{v12}', v1, v21) flag.newFlag(f'f{v12}', v21, v12) flag.newFlag(f'f{v12}', v12, v1) v1, v2 = v2, v3 # current becomes previous vert1, vert2 = vert2, vert3 newpoly = flag.topoly() newpoly.name = f'P{poly.name}' return newpoly
def kisN(poly: polyhedron, n: int = 0, apexdist=0.1) -> polyhedron: flag = polyflag() for i, v in enumerate( poly.vertices): # each old vertex is a new vertex flag.newV(f'v{i}', v) normals = poly.normals centers = poly.calc_centers() foundAny = False for i in range(len(poly.faces)): f = poly.faces[i] v1 = f'v{f[len(f) - 1]}' for v in f: v2 = f'v{v}' if len(f) == n or n == 0: foundAny = True apex = f'apex{i}' fname = f'{i}{v1}' # new vertices in centers of n-sided face flag.newV(apex, add(centers[i], mult(apexdist, normals[i]))) flag.newFlag(fname, v1, v2) # the old edge of original face flag.newFlag(fname, v2, apex) # up to apex of pyramid flag.newFlag(fname, apex, v1) # and back down again else: flag.newFlag(f'{i}', v1, v2) # same old flag, if non-n # current becomes previous v1 = v2 if not foundAny: pass # print(f'No {n} - fold components were found.') newpoly = flag.topoly() newpoly.name = f'k{"" if n is 0 else n}{poly.name}' return newpoly
def whirl(poly: polyhedron, n=0) -> polyhedron: flag = polyflag() for i, v in enumerate( poly.vertices): # each old vertex is a new vertex flag.newV(f'v{i}', unit(v)) centers = poly.centers for i, f in enumerate(poly.faces): v1, v2 = f[-2:] for j, v in enumerate(f): v3 = v # New vertex along edge v1_2 = oneThird(poly.vertices[v1], poly.vertices[v2]) flag.newV(f'{v1}~{v2}', v1_2) # New vertices near center of face cv1name = f'center{i}~{v1}' cv2name = f'center{i}~{v2}' flag.newV(cv1name, unit(oneThird(centers[i], v1_2))) fname = f'{i}f{v1}' # New hexagon for each original edge flag.newFlag(fname, cv1name, f'{v1}~{v2}') flag.newFlag(fname, f'{v1}~{v2}', f'{v2}~{v1}') flag.newFlag(fname, f'{v2}~{v1}', f'v{v2}') flag.newFlag(fname, f'v{v2}', f'{v2}~{v3}') flag.newFlag(fname, f'{v2}~{v3}', cv2name) flag.newFlag(fname, cv2name, cv1name) # New face in center of each old face flag.newFlag(f'c{i}', cv1name, cv2name) v1, v2 = v2, v3 newpoly = flag.topoly() newpoly.name = f'w{poly.name}' return newpoly