Source code for flatsurf.graphical.surface

from sage.matrix.matrix_space import MatrixSpace
from sage.modules.free_module import VectorSpace
from sage.rings.real_double import RDF
from sage.rings.rational_field import QQ

from flatsurf.geometry.similarity_surface import SimilaritySurface_generic
from flatsurf.graphical.polygon import *
from flatsurf.graphical.edge_gluings import *


[docs]class GraphicalSurface: r""" EXAMPLES:: sage: from flatsurf import * sage: from flatsurf.graphical.surface import GraphicalSurface sage: s = similarity_surfaces.example() sage: gs = GraphicalSurface(s) sage: gs.graphical_polygon(0).set_fill_color("red") sage: gs.graphical_polygon(0).plot() Graphics object consisting of 2 graphics primitives """ def __init__(self, similarity_surface, name=None): r""" Construct a GraphicalSurface from a similarity surface. """ if name is None: name="Graphical Surface based on "+repr(similarity_surface) assert isinstance(similarity_surface, SimilaritySurface_generic) self._ss = similarity_surface self._field = self._ss.base_ring() # Polygons self._polygons = {} # Set of visible polygons self._visible = set() label = self._ss.base_label() self._visible.add(label) self._polygons[label] = GraphicalPolygon(self._ss.polygon(label), label=label) def __repr__(self): return "Graphical version of Similarity Surface {!r}".format(self._ss)
[docs] def visible(self): r""" Return the set of visible labels. """ return self._visible
[docs] def is_visible(self,label): r""" Return whether the polygon with the given label is marked as visible. """ return label in self._visible
[docs] def make_visible(self,label): r""" Mark the polygon with the given label as visible. """ self._visible.add(label)
[docs] def make_all_visible(self): r"""Attempt to show all invisible polygons by walking over the surface.""" assert self._ss.is_finite() for l in self._ss.polygon_labels(): poly = self._ss.polygon(l) for e in range(poly.base_polygon().num_edges()): l2,e2 = self._ss.opposite_edge(l,e) if not self.is_visible(l2): self.make_adjacent_and_visible(l,e)
[docs] def get_surface(self): r""" Return the underlying similarity surface. """ return self._ss
[docs] def minx(self): r""" Return the minimal x-coordinate of a vertex of a visible graphical polygon. .. TODO:: this should be xmin """ return min([self.graphical_polygon(label).minx() for label in self.visible()])
[docs] def miny(self): r""" Return the minimal y-coordinate of a vertex of a visible graphical polygon. .. TODO:: this should be ymin """ return min([self.graphical_polygon(label).miny() for label in self.visible()])
[docs] def maxx(self): r""" Return the maximal x-coordinate of a vertex of a visible graphical polygon. .. TODO:: this should be xmax """ return max([self.graphical_polygon(label).maxx() for label in self.visible()])
[docs] def maxy(self): r""" Return the minimal y-coordinate of a vertex of a visible graphical polygon. .. TODO:: this should be ymax """ return max([self.graphical_polygon(label).maxy() for label in self.visible()])
[docs] def bounding_box(self): r""" Return the quadruple (x1,y1,x2,y2) where x1 and y1 are the minimal x- and y-coordinates of a visible graphical polygon and x2 and y2 are the maximal x-and y- cordinates of a visible graphical polygon. """ return self.minx(), self.miny(), self.maxx(), self.maxy()
[docs] def graphical_polygon(self, label): r""" Return the graphical_polygon with the given label. """ if self._polygons.has_key(label): return self._polygons[label] else: p = GraphicalPolygon(self._ss.polygon(label), label=label) self._polygons[label] = p return p
[docs] def make_adjacent(self, p, e): r""" Move the polygon across the prescribed edge so that is adjacent. EXAMPLES:: sage: from flatsurf.geometry.similarity_surface_generators import SimilaritySurfaceGenerators sage: s = SimilaritySurfaceGenerators.example() sage: from flatsurf.graphical.surface import GraphicalSurface sage: gs = GraphicalSurface(s) sage: print("Polygon 0: "+str(gs.graphical_polygon(0).vertices())) Polygon 0: [(0.0, 0.0), (2.0, -2.0), (2.0, 0.0)] sage: print("Polygon 1: "+str(gs.graphical_polygon(1).vertices())) Polygon 1: [(0.0, 0.0), (2.0, 0.0), (1.0, 3.0)] sage: print("Polygon 0, edge 0 is opposite "+str(gs.opposite_edge(0,0))) Polygon 0, edge 0 is opposite (1, 1) sage: gs.make_adjacent(0,0) sage: print("Polygon 0: "+str(gs.graphical_polygon(0).vertices())) Polygon 0: [(0.0, 0.0), (2.0, -2.0), (2.0, 0.0)] sage: print("Polygon 1: "+str(gs.graphical_polygon(1).vertices())) Polygon 1: [(0.4, -2.8), (2.0, -2.0), (0.0, 0.0)] """ pp,ee = self._ss.opposite_edge(p,e) poly = self.graphical_polygon(pp) g = self._ss.edge_transformation(pp,ee) h = self.graphical_polygon(p).transformation() poly.set_transformation(h*g)
[docs] def make_adjacent_and_visible(self, p, e): r"""Move the polygon across the prescribed edge so that is adjacent, and make the moved polygon visible.""" self.make_adjacent(p, e) self.make_visible(self._ss.opposite_edge(p,e)[0])
[docs] def is_adjacent(self,p,e): r""" Returns the truth value of the statement 'The polygon opposite edge (p,e) is adjacent to that edge.' """ pp,ee = self.opposite_edge(p,e) return self.graphical_polygon(p).transformed_vertex(e)==self.graphical_polygon(pp).transformed_vertex(ee+1) and \ self.graphical_polygon(p).transformed_vertex(e+1)==self.graphical_polygon(pp).transformed_vertex(ee)
[docs] def opposite_edge(self, p, e): r""" Given the label ``p`` of a polygon and an edge ``e`` in that polygon returns the pair (``pp``, ``ee``) to which this edge is glued. """ return self._ss.opposite_edge(p,e)
[docs] def plot(self): r""" Returns a plot of the GraphicalSurface EXAMPLES:: sage: from flatsurf.geometry.similarity_surface_generators import SimilaritySurfaceGenerators sage: s = SimilaritySurfaceGenerators.example() sage: from flatsurf.graphical.surface import GraphicalSurface sage: gs = GraphicalSurface(s) sage: gs.make_visible(1) sage: gs.plot() Graphics object consisting of 9 graphics primitives """ i = iter(self._visible) label = i.next() polygon = self.graphical_polygon(label) p = polygon.plot() for e in range(polygon.base_polygon().num_edges()): if not self.is_adjacent(label,e): p += polygon.plot_edge(e,color="blue") else: pp,ee = self.opposite_edge(label,e) if label>pp or (label == pp and e > ee): p += polygon.plot_edge(e,color="blue",dotted=True) for label in i: polygon = self.graphical_polygon(label) p += polygon.plot() for e in range(polygon.base_polygon().num_edges()): if not self.is_adjacent(label,e): p += polygon.plot_edge(e,color="blue") else: pp,ee = self.opposite_edge(label,e) if label>pp or (label == pp and e > ee): p += polygon.plot_edge(e,color="blue",dotted=True) return p