def toDrawables(self, elements, tile=None, layer=0, **kwargs): #class which assists in drawing more information on same github link if tile is None: trans = Transform.identity() codes = range(self.p1) else: trans = tile.trans codes = [side.code[1] for side in tile.sides] polys = [ Polygon.fromRestorePoints(trans.applyToList(desc)) for desc in self.polyDescs ] ds = [] if layer == 0: for i, poly in enumerate(polys[1:]): color = self.colors[codes[i]] d = poly.toDrawables(elements, fill=color, opacity=0.5, **kwargs) ds.extend(d) if layer == 1: dLast = polys[0].toDrawables(elements, hwidth=0.03, fill='white', **kwargs) ds.extend(dLast) if layer == 2: for i, poly in enumerate(polys[1:]): d = poly.toDrawables(elements, hwidth=0.01, fill='black', **kwargs) ds.extend(d) return ds
def __init__(self, p1=4, p2=3, q=3): theta1, theta2 = math.pi * 2 / p1, math.pi * 2 / p2 phiSum = math.pi * 2 / q r1 = triangleSideForAngles(theta1 / 2, phiSum / 2, theta2 / 2) r2 = triangleSideForAngles(theta2 / 2, phiSum / 2, theta1 / 2) tGen1 = htiles.TileGen.makeRegular(p1, hr=r1) tGen2 = htiles.TileGen.makeRegular(p2, hr=r2) t1 = tGen1.centeredTile() t2 = tGen2.placedAgainstTile(t1, side=-1) t3 = tGen1.placedAgainstTile(t2, side=-1) pointBase = t3.vertices[-1] points = [ Transform.rotation(deg=i * 360 / p1).applyToPoint(pointBase) for i in range(p1) ] vertices = t1.vertices edges = [] for i, point in enumerate(points): v1 = vertices[i] v2 = vertices[(i + 1) % p1] edge = Hypercycle.fromPoints(*v1, *v2, *point, segment=True, excludeMid=True) edges.append(edge) edgePoly = Polygon(edges=edges, vertices=vertices) origin = Point(0, 0) corner = Point.fromHPolar(r1, theta=0) corner2 = Transform.rotation(rad=theta1).applyToPoint(corner) center = Point.fromHPolar(r2, theta=math.pi - phiSum / 2) center = Transform.translation(corner).applyToPoint(center) poly = Polygon.fromVertices((origin, corner, center, corner2)) desc = poly.makeRestorePoints() descs = [ Transform.rotation(deg=i * 360 / p1).applyToList(desc) for i in range(p1) ] super().__init__(edgePoly, polyDescs=descs) self.p1 = p1 self.p2 = p2 self.colors = ['#ffbf00', 'purple', 'red', 'blue', 'gray', 'brown']
def render( self, output, image_size, show_vertices_labels=False, draw_alternative_domains=True, draw_polygon_edges=True, draw_inner_lines=False, draw_labelled_edges=False, vertex_size=0.1, line_width=0.07, checker=False, checker_colors=("#1E7344", "#EAF78D"), face_colors=("lightcoral", "mistyrose", "steelblue"), ): trans = Transform.merge(Transform.diskToHalf(), Transform.translation((-0.00001, 0))) d = drawSvg.Drawing(12, 6, origin=(-6, 0)) d.append(drawSvg.Rectangle(-10, -10, 20, 20, fill="silver")) bar = tqdm.tqdm(desc="processing polygons", total=self.num_faces) # draw the faces for (i, j), flist in self.face_indices.items(): if checker: style1 = {"fill": checker_colors[0]} style2 = {"fill": checker_colors[1]} else: vertex_index = self.vertex_at_mirrors(i, j) color = face_colors[vertex_index] style1 = {"fill": color} style2 = {"fill": color, "opacity": 0.3} for k, face in enumerate(flist): # coords of the vertices of this face points = [self.project(p) for p in face.coords] polygon = Polygon.fromVertices(points) # compute the alternate domains domain1, domain2 = face.get_alternative_domains() domain1_2d = [[self.project(p) for p in D] for D in domain1] domain2_2d = [[self.project(p) for p in D] for D in domain2] # draw domains of even reflections for D in domain1_2d: poly = Polygon.fromVertices(D) d.draw(poly, transform=trans, **style1) if checker: d.draw(poly, transform=trans, hwidth=0.005, **style1) if draw_inner_lines: d.draw(poly, transform=trans, fill="papayawhip", hwidth=0.015) # draw domains of odd reflections for D in domain2_2d: poly = Polygon.fromVertices(D) d.draw(poly, transform=trans, **style2) if checker: d.draw(poly, transform=trans, hwidth=0.005, **style2) if draw_inner_lines: d.draw(poly, transform=trans, fill="papayawhip", hwidth=0.015) # outmost polygon contours if draw_polygon_edges: d.draw( polygon, transform=trans, hwidth=line_width, fill="darkolivegreen", ) bar.update(1) bar.close() # draw the edges with white strips if draw_labelled_edges: for k, elist in self.edge_indices.items(): if k != 0: for i, j in elist: p = self.project(self.vertices_coords[i]) q = self.project(self.vertices_coords[j]) hl = Line.fromPoints(p[0], p[1], q[0], q[1], segment=True) if k == 1: x = divide_line(line_width, 1) d.draw(hl, transform=trans, hwidth=(-x, x), fill="papayawhip") if k == 2: x1, x2 = divide_line(line_width, 2) d.draw(hl, transform=trans, hwidth=(x1, x2), fill="papayawhip") d.draw( hl, transform=trans, hwidth=(-x2, -x1), fill="papayawhip", ) # draw vertices with labels if show_vertices_labels: for i, p in enumerate(self.vertices_coords): loc = self.project(p) P = Point(*loc) d.draw(P, transform=trans, hradius=vertex_size, fill="darkolivegreen") Q = trans.applyToTuple(P) x_, y_, r_ = get_euclidean_center_radius_uhp(Q, vertex_size) d.append( drawSvg.Text(str(i), r_, x_, y_, center=0.7, fill="white")) d.append(drawSvg.Rectangle(-20, 0, 40, 0.02, fill="#000")) d.setRenderSize(w=image_size[0], h=image_size[1]) d.saveSvg(output) size = os.path.getsize(output) >> 10 print("{}KB svg file has been written to disk".format(size)) print("=" * 40)
def RotationAt(P, radians): TPO = Transform.shiftOrigin(P) # sends P to origin return Transform.merge(TPO, Transform.rotation(rad=radians), TPO.inverted())
def Translation(P, Q): def negative(P): return Point(-P.x, -P.y) TPO = Transform.shiftOrigin(P) # sends P to origin Treal = Transform.shiftOrigin(negative(TPO(Q)[0])) # sends origin to TPO(Q) return Transform.merge(TPO, Treal, TPO.inverted())
def left(self, radians): TToOrigin = Transform.shiftOrigin(self.point) TRotation = Transform.merge(TToOrigin, Transform.rotation(rad=radians), TToOrigin.inverted()) return Turtle(self.point, TRotation(self.head)[0])
def forward(self, distance): TForward = Transform.shiftOrigin(Point(math.tanh(-distance/2), 0)) TToOrigin = self.transformToOrigin() TFromOrigin = TToOrigin.inverted() T = Transform.merge(TToOrigin, TForward, TFromOrigin) return Turtle(*T(self.point, self.head))
def transformToOrigin(self): """ Transformation mapping self to origin, pointing along x-axis. """ return Transform.shiftOrigin(self.point, self.head)
r2 = triangleSideForAngles(theta2 / 2, phiSum / 2, theta1 / 2) tGen1 = htiles.TileGen.makeRegular(p1, hr=r1, skip=1) tGen2 = htiles.TileGen.makeRegular(p2, hr=r2, skip=1) tLayout = htiles.TileLayout() tLayout.addGenerator(tGen1, (1, ) * p1) tLayout.addGenerator(tGen2, (0, ) * p2, htiles.TileDecoratorNull()) startTile = tLayout.defaultStartTile(rotateDeg=rotate) t1 = startTile t2 = tLayout.placeTile(t1.sides[-1]) t3 = tLayout.placeTile(t2.sides[-1]) pointBase = t3.vertices[-1] points = [ Transform.rotation(deg=i * 360 / p1).applyToPoint(pointBase) for i in range(p1) ] vertices = startTile.vertices edges = [] for i, point in enumerate(points): v1 = vertices[i] v2 = vertices[(i + 1) % p1] edge = Hypercycle.fromPoints(*v1, *v2, *point, segment=True, excludeMid=True) edges.append(edge) decoratePoly = Polygon(edges=edges, vertices=vertices) decorator1 = htiles.TileDecoratorPolygons(decoratePoly)