def render_spiral(self, initial_elements, sides, max_height, file_name, initial_colors=(), color_dic=None): """ Create an image file depicting a flower complex. Note that the identification between colors and elements is not preserved across images with different `sides` and `max_layer` values unless a color dictionary is provided. Don't be misled by this. Args: initial_elements (tuple): The first elements to be operated on. sides (int): The number of sides of the original polygon. max_beight (int): The number of steps up from the origin to construct. file_name (str): The name of the file generated. intial_colors (tuple): Colors used to display the complex. These are used before the colors in `self.initial_colors`. color_dic (dict): Dictionary of colors to be used when displaying the complex. This is used before the dictionary in `self.color_dic`. """ values = self.grow_spiral(initial_elements, sides, max_height) while color_dic is None: color_dic = self.color_dic color_dic = self.color_dictionary(values, initial_colors) g = 0 loc = lambda b, c, a=1: polar_location( a, b, sides, height=c, dimension=3) for h in range(max_height): for n in range(sides - 1): p1 = loc(0, h, 0) p2 = loc(n, h) p3 = loc(n + 1, h) c1 = color_dic[values[0][0]] # left input c2 = color_dic[values[h + 1][n]] # right input c3 = color_dic[values[h + 1][n + 1]] # output sub_div = barycentric_subdivision(p1, p2, p3) cols = (c1, c2, c3, c3) for i in range(4): g += polygon(sub_div[i], color=cols[i]) if h != max_height - 1: p1 = loc(0, h, 0) p2 = loc(sides - 1, h) p3 = loc(0, h + 1) c1 = color_dic[values[0][0]] # left input c2 = color_dic[values[h + 1][sides - 1]] # right input c3 = color_dic[values[h + 2][0]] # output sub_div = barycentric_subdivision(p1, p2, p3) cols = (c1, c2, c3, c3) for i in range(4): g += polygon(sub_div[i], color=cols[i]) g.save(file_name + '.x3d', axes=False)
def plot_n_cylinders(self, n, labels=True): r""" EXAMPLES:: sage: from slabbe.markov_transformation import markov_transformations sage: T = markov_transformations.Selmer() sage: G = T.plot_n_cylinders(3) TESTS:: sage: G = T.plot_n_cylinders(0) """ from sage.plot.graphics import Graphics from sage.plot.polygon import polygon from sage.plot.text import text M3to2 = projection_matrix(3, 2) G = Graphics() for w, cyl in self.n_cylinders_iterator(n): columns = cyl.columns() G += polygon((M3to2 * col / col.norm(1) for col in columns), fill=False) if labels: sum_cols = sum(columns) G += text("{}".format(w), M3to2 * sum_cols / sum_cols.norm(1)) return G
def plot_n_cylinders(self, n, labels=True): r""" EXAMPLES:: sage: from slabbe.matrix_cocycle import cocycles sage: C = cocycles.Sorted_ARP() sage: G = C.plot_n_cylinders(3) """ from sage.plot.graphics import Graphics from sage.plot.polygon import polygon from sage.plot.text import text from matrices import M3to2 G = Graphics() for w,cyl in self.n_cylinders_iterator(n): columns = cyl.columns() G += polygon((M3to2*col/col.norm(1) for col in columns), fill=False) if labels: sum_cols = sum(columns) G += text("{}".format(w), M3to2*sum_cols/sum_cols.norm(1)) return G
def plot_n_cylinders(self, n, labels=True): r""" EXAMPLES:: sage: from slabbe.matrix_cocycle import cocycles sage: C = cocycles.Sorted_ARP() sage: G = C.plot_n_cylinders(3) """ from sage.plot.graphics import Graphics from sage.plot.polygon import polygon from sage.plot.text import text from .matrices import M3to2 G = Graphics() for w,cyl in self.n_cylinders_iterator(n): columns = cyl.columns() G += polygon((M3to2*col/col.norm(1) for col in columns), fill=False) if labels: sum_cols = sum(columns) G += text("{}".format(w), M3to2*sum_cols/sum_cols.norm(1)) return G
def polygon_plot3d(points, tilt=30, turn=30, **kwargs): """ Plots a polygon viewed from an angle determined by tilt, turn, and vertices points. .. warning:: The ordering of the points is important to get "correct" and if you add several of these plots together, the one added first is also drawn first (ie, addition of Graphics objects is not commutative). The following example produced a green-colored square with vertices at the points indicated. EXAMPLES:: sage: from sage.groups.perm_gps.cubegroup import * sage: P = polygon_plot3d([[1,3,1],[2,3,1],[2,3,2],[1,3,2],[1,3,1]],rgbcolor=green) """ rot = rotation_list(tilt,turn) points2 = [(xproj(x,y,z,rot), yproj(x,y,z,rot)) for (x,y,z) in points ] return polygon(points2, **kwargs)
def plot_n_cylinders(self, n, labels=True): r""" EXAMPLES:: sage: from slabbe.markov_transformation import markov_transformations sage: T = markov_transformations.Selmer() sage: G = T.plot_n_cylinders(3) TESTS:: sage: G = T.plot_n_cylinders(0) """ from sage.plot.graphics import Graphics from sage.plot.polygon import polygon from sage.plot.text import text M3to2 = projection_matrix(3, 2) G = Graphics() for w,cyl in self.n_cylinders_iterator(n): columns = cyl.columns() G += polygon((M3to2*col/col.norm(1) for col in columns), fill=False) if labels: sum_cols = sum(columns) G += text("{}".format(w), M3to2*sum_cols/sum_cols.norm(1)) return G
def add_rightside(i, j, k): return polygon(move(Rside,i,j,k), edgecolor="black", color=colors[2])
def add_leftside(i, j, k): return polygon(move(Lside,i,j,k), edgecolor="black", color=colors[1])
def add_topside(i, j, k): return polygon(move(Uside,i,j,k), edgecolor="black", color=colors[0])
def render_complex(self, file_name, cycles=1, degenerate_faces=True, initial_colors=(), color_dic=None): """ Create 3d graphics depicting a binary operation complex. Vertices are placed on a helix which winds around the surface of the sphere with center (0,0,1/2) and radius 1/2. That is, the first vertex is placed at (0,0,0) and the last is placed at (0,0,1). Args: file_name (str): The name of the file generated. cycles (int): The number of times the determining helix winds around the line between the origin and (0,0,1). intial_colors (tuple): Colors used to display the complex. These are used before the colors in `self.initial_colors`. color_dic (dict): Dictionary of colors to be used when displaying the complex. This is used before the dictionary in `self.color_dic`. """ elems = tuple(self.structure.elements) f = self.operation while color_dic is None: color_dic = self.color_dic color_dic = self.color_dictionary((elems, ), initial_colors) g = 0 loc = lambda a, b, c: (sin(c * pi) * cos(a * 2 * pi / b), sin(c * pi) * sin(a * 2 * pi / b), c) locations = {} for h in range(len(elems)): locations[elems[h]] = loc(cycles * h, len(elems), h / len(elems)) for x in elems: for y in elems: z = self.operation(x, y) if degenerate_faces: if x == y: # x=y=z case if x == z: if locations[x] == (0, 0, 0): p1, p2, p3, p4 = (0, 0, 0), loc( 0, 3, -1 / 2), loc(1, 3, -1 / 2), loc(2, 3, -1 / 2) for entry in ((p1, p2, p3), (p1, p2, p4), (p1, p3, p4), (p2, p3, p4)): g += polygon(entry, colors=color_dic[x]) if locations[x] == (0, 0, 1): p1, p2, p3, p4 = (0, 0, 1), loc( 0, 3, 3 / 2), loc(1, 3, 3 / 2), loc(2, 3, 3 / 2) for entry in ((p1, p2, p3), (p1, p2, p4), (p1, p3, p4), (p2, p3, p4)): g += polygon(entry, colors=color_dic[x]) if locations[x] != (0, 0, 0) and locations[x] != ( 0, 0, 1): p1 = locations[x] p2 = tuple( map( add, map(lambda u: 14 * u / 10, locations[x]), map( lambda u: 6 * u / 10, locations[elems[elems.index(x) + 1]]))) p3 = tuple( map( add, map(lambda u: 14 * u / 10, locations[x]), map( lambda u: 6 * u / 10, locations[elems[elems.index(x) - 1]]))) p4 = tuple( map( add, map(lambda u: 14 * u / 10, locations[x]), map(lambda u: 6 * u / 10, map(add, locations[x], (0, 0, 1))))) for entry in ((p1, p2, p3), (p1, p2, p4), (p1, p3, p4), (p2, p3, p4)): g += polygon(entry, colors=color_dic[x]) # x=y or x=z or y=z case if (x == y and x != z) or (x == z and x != y) or (y == z and x != y): if x == y: s, t = x, z if x == z: s, t = x, y if y == z: s, t = x, z p1 = locations[s] p2 = locations[t] a = map(lambda u: u / 2, map(add, p1, p2)) b = map(subtract, p1, p2) p3 = map(add, a, cross(b, (0, 0, 1))) p4 = map(add, p3, (0, 0, 1 / len(elems))) polys = ((p1, p2, p3), (p1, p2, p4), (p1, p3, p4), (p2, p3, p4)) cols = (color_dic[s], color_dic[t], color_dic[s], color_dic[t]) for i in range(4): g += polygon(polys[i], colors=cols[i]) # x,y,z are distinct case if x != y and x != z and y != z: if f(x, y) == f(y, x): p1, p2, p3 = locations[x], locations[y], locations[z] p4 = cross(map(subtract, p1, p2), map(subtract, p1, p3)) c1, c2, c3 = color_dic[x], color_dic[y], color_dic[z] cols = (c1, c2, c3) faces = ((p1, p2, p4), (p1, p3, p4), (p2, p3, p4)) for i in range(3): g += polygon(faces[i], color=cols[i]) else: p1, p2, p3 = locations[x], locations[y], locations[z] c1, c2, c3 = color_dic[x], color_dic[y], color_dic[z] sub_div = barycentric_subdivision(p1, p2, p3) cols = (c1, c2, c3, c3) for i in range(4): g += polygon(sub_div[i], color=cols[i]) g.save(file_name + '.x3d', axes=False)
def render_flower(self, initial_elements, sides, max_layer, file_name, dimension=2, use_height=False, initial_colors=(), color_dic=None): """ Create an image file depicting a flower complex. Note that the identification between colors and elements is not preserved across images with different `sides` and `max_layer` values unless a color dictionary is provided. Don't be misled by this. Also note that `max_layer` cannot be set much higher than `sides` without triangles overlapping. This can be dealt with in 3-space by using the `use_height` setting. Args: initial_elements (tuple): The first elements to be operated on. sides (int): The number of sides of the original polygon. max_layer (int): The number of steps out from the origin to construct. file_name (str): The name of the file generated. dim (int): The number of coordinate axes in the plot space. use_height (bool): If `dimension` is 3 then make use of the extra room in space. intial_colors (tuple): Colors used to display the complex. These are used before the colors in `self.initial_colors`. color_dic (dict): Dictionary of colors to be used when displaying the complex. This is used before the dictionary in `self.color_dic`. """ values = self.grow_flower(initial_elements, sides, max_layer) while color_dic is None: color_dic = self.color_dic color_dic = self.color_dictionary(values, initial_colors) g = 0 loc = lambda a, b, c=0: polar_location( a, b, sides, height=c, dimension=dimension) # initial points for n in range(sides - 1): p1 = (0, ) * dimension p2 = loc(1, n) p3 = loc(1, n + 1) if dimension == 3 and use_height: p2 = loc(1, n, 1) p3 = loc(1, n + 1, 1) c1 = color_dic[values[0][0]] # left input c2 = color_dic[values[1][n]] # right input c3 = color_dic[values[1][n + 1]] # output sub_div = barycentric_subdivision(p1, p2, p3) cols = (c1, c2, c3, c3) for i in range(4): g += polygon(sub_div[i], color=cols[i]) # subsequent points for r in range(1, max_layer - 1): for n in range(sides): p1 = loc(r, n) p2 = loc(r, n + 1) p3 = loc(r + 1, n) if dimension == 3 and use_height: p1 = loc(r, n, r) p2 = loc(r, n + 1, r) p3 = loc(r + 1, n, r + 1) c1 = color_dic[values[r][n]] # left input c2 = color_dic[values[r][(n + 1) % sides]] # right input c3 = color_dic[values[r + 1][n]] # output sub_div = barycentric_subdivision(p1, p2, p3) cols = (c1, c2, c3, c3) for i in range(4): g += polygon(sub_div[i], color=cols[i]) if dimension == 2: g.save(file_name + '.svg', axes=False) if dimension == 3: g.save(file_name + '.x3d')
def create_poly(face, color): return polygon(face_polys[face], rgbcolor=color)