surface
¶
Generic mutable and immutable surfaces
This module provides base classes and implementations of surfaces. Most surfaces in sage-flatsurf inherit from some of the classes in this module.
The most important class in this module is
MutableOrientedSimilaritySurface
which allows you to create a surface
by gluing polygons with similarities.
EXAMPLES:
We build a translation surface by gluing two hexagons, labeled 0 and 1:
sage: from flatsurf import MutableOrientedSimilaritySurface, polygons
sage: S = MutableOrientedSimilaritySurface(QuadraticField(3))
sage: S.add_polygon(polygons.regular_ngon(6))
0
sage: S.add_polygon(polygons.regular_ngon(6))
1
sage: S.glue((0, 0), (1, 3))
sage: S.glue((0, 1), (1, 4))
sage: S.glue((0, 2), (1, 5))
sage: S.glue((0, 3), (1, 0))
sage: S.glue((0, 4), (1, 1))
sage: S.glue((0, 5), (1, 2))
sage: S
Translation Surface built from 2 regular hexagons
We signal that the construction is complete. This refines the category of the surface and makes more functionality available:
sage: S.set_immutable()
sage: S
Translation Surface in H_2(1^2) built from 2 regular hexagons
- class flatsurf.geometry.surface.BaseRingChangedSurface(surface, ring, category=None)[source]¶
Changes the ring over which a surface is defined.
EXAMPLES:
This class is used in the implementation of
flatsurf.geometry.categories.similarity_surfaces.SimilaritySurfaces.Oriented.ParentMethods.change_ring()
:sage: from flatsurf import translation_surfaces sage: T = translation_surfaces.square_torus() sage: S = T.change_ring(AA) sage: from flatsurf.geometry.surface import BaseRingChangedSurface sage: isinstance(S, BaseRingChangedSurface) True sage: TestSuite(S).run()
- __annotations__ = {}¶
- __eq__(other)[source]¶
Return whether this surface is indistinguishable from
other
.See
_test_eq_surface()
for details on this notion of equality.EXAMPLES:
sage: from flatsurf import translation_surfaces sage: T = translation_surfaces.square_torus() sage: T.change_ring(AA) == T.change_ring(AA) True
- __hash__()[source]¶
Return a hash value for this surface that is compatible with
__eq__()
.EXAMPLES:
sage: from flatsurf import translation_surfaces sage: T = translation_surfaces.square_torus() sage: hash(T.change_ring(AA)) == hash(T.change_ring(AA)) True
- __module__ = 'flatsurf.geometry.surface'¶
- is_mutable()[source]¶
Return whether this surface can be modified, i.e., return
False
.This implements
flatsurf.geometry.categories.topological_surfaces.TopologicalSurfaces.ParentMethods.is_mutable()
.EXAMPLES:
sage: from flatsurf import translation_surfaces sage: T = translation_surfaces.square_torus() sage: S = T.change_ring(AA) sage: S.is_mutable() False
- labels()[source]¶
Return the labels of the polygons of this surface.
EXAMPLES:
sage: from flatsurf import translation_surfaces sage: T = translation_surfaces.square_torus() sage: S = T.change_ring(AA) sage: S.labels() (0,)
- opposite_edge(label, edge)[source]¶
Return the edge that
edge
oflabel
is glued to orNone
if this edge is unglued.This implements
flatsurf.geometry.categories.polygonal_surfaces.PolygonalSurfaces.ParentMethods.opposite_edge()
.EXAMPLES:
sage: from flatsurf import translation_surfaces sage: T = translation_surfaces.square_torus() sage: S = T.change_ring(AA) sage: S.opposite_edge(0, 0) (0, 2)
- polygon(label)[source]¶
Return the polygon with
label
.This implements
flatsurf.geometry.categories.polygonal_surfaces.PolygonalSurfaces.ParentMethods.polygon()
.EXAMPLES:
sage: from flatsurf import translation_surfaces sage: T = translation_surfaces.square_torus() sage: S = T.change_ring(AA) sage: p = S.polygon(0) sage: p.base_ring() Algebraic Real Field
- roots()[source]¶
Return a label for each connected component on this surface.
This implements
flatsurf.geometry.categories.polygonal_surfaces.PolygonalSurfaces.ParentMethods.roots()
.EXAMPLES:
sage: from flatsurf import translation_surfaces sage: T = translation_surfaces.square_torus() sage: S = T.change_ring(AA) sage: S.roots() (0,)
- class flatsurf.geometry.surface.ComponentLabels(surface, root, finite=None)[source]¶
The labels of a connected component.
INPUT:
surface
– a polygonal surfaceroot
– a label of the connected component from which enumeration of the component starts.finite
– a boolean orNone
(default:None
); whether this is a finite component; ifNone
, it is not known whether the component is finite (some operations might not be supported in that case or not terminate if the component is actually infinite.)
EXAMPLES:
sage: from flatsurf import translation_surfaces sage: S = translation_surfaces.t_fractal() sage: component = S.component(0) sage: from flatsurf.geometry.surface import ComponentLabels sage: isinstance(component, ComponentLabels) True
- __abstractmethods__ = frozenset({})¶
- __annotations__ = {}¶
- __iter__()[source]¶
Return an iterator of this component that enumerates labels starting from the root label in a breadth-first-search.
EXAMPLES:
sage: from flatsurf import translation_surfaces sage: C = translation_surfaces.cathedral(1, 2) sage: component = C.component(0) sage: list(component) [0, 1, 3, 2]
- __module__ = 'flatsurf.geometry.surface'¶
- class flatsurf.geometry.surface.Edges(surface, finite=None)[source]¶
The set of edges of a surface.
The set of edges contains of pairs (label, index) with the labels of the polygons and the actual edges indexed from 0 in the second component.
EXAMPLES:
sage: from flatsurf import translation_surfaces sage: C = translation_surfaces.cathedral(1, 2) sage: edges = C.edges() sage: edges ((0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (2, 0), (2, 1), (2, 2), (2, 3))
- __abstractmethods__ = frozenset({})¶
- __annotations__ = {}¶
- __module__ = 'flatsurf.geometry.surface'¶
- class flatsurf.geometry.surface.Gluings(surface, finite=None)[source]¶
The set of gluings of the surface.
Each gluing consists of two pairs (label, index) that describe the edges being glued.
Note that each gluing (that is not a self-gluing) is reported twice.
EXAMPLES:
sage: from flatsurf import translation_surfaces sage: S = translation_surfaces.square_torus() sage: gluings = S.gluings() sage: gluings (((0, 0), (0, 2)), ((0, 1), (0, 3)), ((0, 2), (0, 0)), ((0, 3), (0, 1)))
- __abstractmethods__ = frozenset({})¶
- __annotations__ = {}¶
- __module__ = 'flatsurf.geometry.surface'¶
- class flatsurf.geometry.surface.LabeledCollection(surface, finite=None)[source]¶
Abstract base class for collection of labels as returned by
labels()
methods of surfaces.This also serves as a base clas for things such as
polygons()
that are tied to labels.INPUT:
surface
– a polygonal surface, the labels are taken from that surface; subclasses might change this to only represent a subset of the labels of this surfacefinite
– a boolean orNone
(default:None
); whether this is a finite set; ifNone
, it is not known whether the set is finite (some operations might not be supported in that case or not terminate if the set is actually infinite.)
EXAMPLES:
sage: from flatsurf import translation_surfaces sage: S = translation_surfaces.square_torus() sage: labels = S.labels() sage: from flatsurf.geometry.surface import LabeledCollection sage: isinstance(labels, LabeledCollection) True
- __abstractmethods__ = frozenset({'__iter__'})¶
- __annotations__ = {}¶
- __contains__(x)[source]¶
Return whether
x
is contained in this set.EXAMPLES:
sage: from flatsurf import translation_surfaces sage: S = translation_surfaces.square_torus() sage: labels = S.labels() sage: 0 in labels True sage: 1 in labels False
- __dict__ = mappingproxy({'__module__': 'flatsurf.geometry.surface', '__doc__': '\n Abstract base class for collection of labels as returned by ``labels()``\n methods of surfaces.\n\n This also serves as a base clas for things such as ``polygons()`` that are\n tied to labels.\n\n INPUT:\n\n - ``surface`` -- a polygonal surface, the labels are taken from that\n surface; subclasses might change this to only represent a subset of the\n labels of this surface\n\n - ``finite`` -- a boolean or ``None`` (default: ``None``); whether this is\n a finite set; if ``None``, it is not known whether the set is finite\n (some operations might not be supported in that case or not terminate if\n the set is actually infinite.)\n\n EXAMPLES::\n\n sage: from flatsurf import translation_surfaces\n sage: S = translation_surfaces.square_torus()\n sage: labels = S.labels()\n\n sage: from flatsurf.geometry.surface import LabeledCollection\n sage: isinstance(labels, LabeledCollection)\n True\n\n ', '__init__': <function LabeledCollection.__init__>, '__repr__': <function LabeledCollection.__repr__>, '__len__': <function LabeledCollection.__len__>, '__contains__': <function LabeledCollection.__contains__>, '__dict__': <attribute '__dict__' of 'LabeledCollection' objects>, '__weakref__': <attribute '__weakref__' of 'LabeledCollection' objects>, '__abstractmethods__': frozenset({'__iter__'}), '_abc_impl': <_abc._abc_data object>, '__annotations__': {}})¶
- __len__()[source]¶
Return the size of this set.
EXAMPLES:
sage: from flatsurf import translation_surfaces sage: S = translation_surfaces.square_torus() sage: len(S.labels()) 1
Python does not allow
__len__
to return anything but an integer, so we cannot return infinity:sage: S = translation_surfaces.infinite_staircase() sage: len(S.labels()) Traceback (most recent call last): ... NotImplementedError: len() of an infinite set
- __module__ = 'flatsurf.geometry.surface'¶
- __repr__()[source]¶
Return a printable representation of this set.
EXAMPLES:
sage: from flatsurf import translation_surfaces sage: S = translation_surfaces.square_torus() sage: S.labels() (0,) sage: S = translation_surfaces.infinite_staircase() sage: S.labels() (0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, …)
- __weakref__¶
list of weak references to the object
- class flatsurf.geometry.surface.LabeledSet(surface, finite=None)[source]¶
Abstract base class for sets of labels or related objects, such as the set of gluings of a surface.
EXAMPLES:
sage: from flatsurf import translation_surfaces sage: S = translation_surfaces.square_torus() sage: gluings = S.gluings() sage: from flatsurf.geometry.surface import LabeledSet sage: isinstance(gluings, LabeledSet) True
- __abstractmethods__ = frozenset({'__iter__'})¶
- __annotations__ = {}¶
- __module__ = 'flatsurf.geometry.surface'¶
- class flatsurf.geometry.surface.LabeledView(surface, view, finite=None)[source]¶
A set of labels (or something resembling labels such as
polygons()
) backed by another collectionview
.INPUT:
surface
– a polygonal surface, the labels inview
are labels of that surfaceview
– a collection that all queries are going to be redirected to. Note thatlabels()
guarantees that iteration over labels happens in a breadth-first-search so iteration overview
must follow that same order. However, subclasses can remove this requirement by overriding__iter__()
.finite
– a boolean orNone
(default:None
); whether this is a finite set; ifNone
, it is not known whether the set is finite (some operations might not be supported in that case or not terminate if the set is actually infinite.)
EXAMPLES:
sage: from flatsurf import translation_surfaces sage: S = translation_surfaces.t_fractal() sage: labels = S.labels() sage: from flatsurf.geometry.surface import LabeledView sage: isinstance(labels, LabeledView) True
- __abstractmethods__ = frozenset({})¶
- __annotations__ = {}¶
- __module__ = 'flatsurf.geometry.surface'¶
- min()[source]¶
Return a minimal item in this set.
If the items can be compared, this is just the actual
min
of the items.Otherwise, we take the one with minimal
repr
.Note
If the items cannot be compared, and there are clashes in the
repr
, this method will fail.Also, if comparison of items is not consistent, then this can produce somewhat random output.
Finally, note with this approach the min of a set is not the always the min of the mins of a each partition of that set.
EXAMPLES:
sage: from flatsurf import translation_surfaces sage: S = translation_surfaces.t_fractal() sage: S.labels().min() Traceback (most recent call last): ... NotImplementedError: cannot determine minimum of an infinite set
sage: from flatsurf import translation_surfaces sage: C = translation_surfaces.cathedral(1,2) sage: C.labels().min() 0
sage: labels = list(C.labels())[:3] sage: from flatsurf.geometry.surface import LabeledView sage: LabeledView(C, labels).min() 0
- class flatsurf.geometry.surface.Labels(surface, finite=None)[source]¶
The labels of a surface.
Note
This is a generic implementation that represents the set of labels of a surface in a breadth-first iteration starting from the root labels of the connected components.
This implementation makes no assumption on the surface and can be very slow to answer, e.g., containment or compute the number of labels in the surface (because it needs to iterate over the entire surface.)
When possible, a faster implementation should be used such as
LabelsFromView
.EXAMPLES:
sage: from flatsurf import polygons, similarity_surfaces sage: T = polygons.triangle(1, 2, 5) sage: S = similarity_surfaces.billiard(T) sage: S = S.minimal_cover("translation") sage: labels = S.labels() sage: labels ((0, 1, 0), (1, 1, 0), (1, 0, -1), (1, 1/2*c0, 1/2*c0), (0, 1/2*c0, -1/2*c0), (0, 0, 1), (0, -1/2*c0, -1/2*c0), (0, 0, -1), (0, -1/2*c0, 1/2*c0), (0, 1/2*c0, 1/2*c0), (1, 1/2*c0, -1/2*c0), (1, -1/2*c0, -1/2*c0), (1, 0, 1), (1, -1/2*c0, 1/2*c0), (1, -1, 0), (0, -1, 0))
- __abstractmethods__ = frozenset({})¶
- __annotations__ = {}¶
- __getitem__(key)[source]¶
Return the labels at position
key
.EXAMPLES:
sage: from flatsurf import translation_surfaces sage: C = translation_surfaces.cathedral(1, 2) sage: labels = C.labels() sage: labels[0] 0 sage: labels[-1] 2 sage: labels[::-1] [2, 3, 1, 0]
- __module__ = 'flatsurf.geometry.surface'¶
- class flatsurf.geometry.surface.LabelsFromView(surface, view, finite=None)[source]¶
The labels of a surface backed by another set that can quickly compute the length of the labels and decide containment in the set.
Note
Iteration of the view collection does not have to be in breadth-first search order in the surface since this class is picking up the generic
Labels.__iter__()
.EXAMPLES:
sage: from flatsurf import translation_surfaces sage: C = translation_surfaces.cathedral(1, 2) sage: labels = C.labels() sage: from flatsurf.geometry.surface import LabelsFromView sage: type(labels) == LabelsFromView True
- __abstractmethods__ = frozenset({})¶
- __annotations__ = {}¶
- __module__ = 'flatsurf.geometry.surface'¶
- class flatsurf.geometry.surface.MutableOrientedSimilaritySurface(base, category=None)[source]¶
A surface built from Euclidean polyogns glued by orientation preserving similarities.
This is the main tool to create new surfaces of finite type in sage-flatsurf.
EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.glue((0, 0), (0, 2)) sage: S.glue((0, 1), (0, 3)) sage: S.set_immutable() sage: S Translation Surface in H_1(0) built from a square
- __annotations__ = {}¶
- __eq__(other)[source]¶
Return whether this surface is indistinguishable from
other
.See
_test_eq_surface()
for details on this notion of equality.EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: T = MutableOrientedSimilaritySurface(AA) sage: S == T False sage: S == S True
- __hash__()[source]¶
Return a hash value for this surface that is compatible with
__eq__()
.EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: T = MutableOrientedSimilaritySurface(QQ) sage: hash(S) == hash(T) Traceback (most recent call last): ... TypeError: cannot hash a mutable surface sage: S.set_immutable() sage: T.set_immutable() sage: hash(S) == hash(T) True
- __module__ = 'flatsurf.geometry.surface'¶
- cmp(s2, limit=None)[source]¶
Compare two surfaces. This is an ordering returning -1, 0, or 1.
The surfaces will be considered equal if and only if there is a translation automorphism respecting the polygons and the root labels.
If the two surfaces are infinite, we just examine the first limit polygons.
- delaunay_single_flip()[source]¶
Perform a single in place flip of a triangulated mutable surface in-place.
- classmethod from_surface(surface, labels=None, category=None)[source]¶
Return a mutable copy of
surface
.INPUT:
labels
– a set of labels orNone
(default:None
); ifNone
, the entire surface is copied, otherwise only these labels are copied and glued like in the original surface.
EXAMPLES:
sage: from flatsurf import translation_surfaces, MutableOrientedSimilaritySurface, polygons sage: T = translation_surfaces.square_torus()
We build a surface that is made from two tori:
sage: S = MutableOrientedSimilaritySurface.from_surface(T) sage: S.add_polygon(polygons.square()) 1 sage: S.glue((1, 0), (1, 2)) sage: S.glue((1, 1), (1, 3))
sage: S.set_immutable()
sage: S Disconnected Surface built from 2 squares
We can build partial copies of an infinite surface:
sage: S = translation_surfaces.infinite_staircase() sage: T = MutableOrientedSimilaritySurface.from_surface(S) Traceback (most recent call last): ... TypeError: cannot create a full copy of an infinite surface sage: T = MutableOrientedSimilaritySurface.from_surface(S, labels=S.labels()[:10]) sage: T.components() ((0, 1, -1, 2, -2, 3, -3, 4, -4, 5),) sage: T = MutableOrientedSimilaritySurface.from_surface(S, labels=S.labels()[:30:3]) sage: T.components() ((0,), (-12,), (-9,), (-6,), (-3,), (2,), (5,), (8,), (11,), (14,))
- glue(x, y)[source]¶
Glue
x
andy
with an (orientation preserving) similarity.INPUT:
x
– a pair consisting of a polygon label and an edge index for that polygony
– a pair consisting of a polygon label and an edge index for that polygon
EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface, polygons sage: S = MutableOrientedSimilaritySurface(QQ) sage: S.add_polygon(polygons.square()) 0
Glue two opposite sides of the square to each other:
sage: S.glue((0, 1), (0, 3))
Glue the other sides of the square to themselves:
sage: S.glue((0, 0), (0, 0)) sage: S.glue((0, 2), (0, 2))
Note that existing gluings are removed when gluing already glued sides:
sage: S.glue((0, 0), (0, 2)) sage: S.set_immutable() sage: S Translation Surface in H_1(0) built from a square
- join_polygons(p1, e1, test=False, in_place=False)[source]¶
Overrides
flatsurf.geometry.categories.similarity_surfaces.SimilaritySurfaces.Oriented.ParentMethods.join_polygons()
to allow joining in-place.
- opposite_edge(label, edge=None)[source]¶
Return the edge that
edge
oflabel
is glued to orNone
if this edge is unglued.This implements
flatsurf.geometry.categories.polygonal_surfaces.PolygonalSurfaces.ParentMethods.opposite_edge()
.INPUT:
label
– one of the labels included inlabels()
edge
– a non-negative integer to specify an edge (the edges of a polygon are numbered starting from zero.)
EXAMPLES:
sage: from flatsurf import Polygon, MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: S.add_polygon(Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)])) 0 sage: S.glue((0, 0), (0, 1)) sage: S.glue((0, 2), (0, 2)) sage: S.opposite_edge(0, 0) (0, 1) sage: S.opposite_edge(0, 1) (0, 0) sage: S.opposite_edge(0, 2) (0, 2) sage: S.opposite_edge(0, 3) sage: S.opposite_edge((0, 0)) doctest:warning ... UserWarning: calling opposite_edge() with a single argument has been deprecated and will be removed in a future version of sage-flatsurf; use opposite_edge(label, edge) instead (0, 1)
- relabel(relabeling=None, in_place=False)[source]¶
Overrides
flatsurf.geometry.categories.similarity_surfaces.SimilaritySurfaces.Oriented.ParentMethods.relabel()
to allow relabeling in-place.
- replace_polygon(label, polygon)[source]¶
Replace the polygon
label
withpolygon
while keeping its gluings intact.INPUT:
label
– an element oflabels()
polygon
– a Euclidean polygon
EXAMPLES:
sage: from flatsurf import Polygon, MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: S.add_polygon(Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)])) 0 sage: S.glue((0, 0), (0, 2)) sage: S.glue((0, 1), (0, 3)) sage: S.replace_polygon(0, Polygon(vertices=[(0, 0), (2, 0), (2, 2), (0, 2)]))
The replacement of a polygon must have the same number of sides:
sage: S.replace_polygon(0, Polygon(vertices=[(0, 0), (2, 0), (2, 2)])) Traceback (most recent call last): ... ValueError: polygon must be a quadrilateral
To replace the polygon without keeping its glueings, remove the polygon first and then add a new one:
sage: S.remove_polygon(0) sage: S.add_polygon(Polygon(vertices=[(0, 0), (2, 0), (2, 2)]), label=0) 0
- reposition_polygons(in_place=False, relabel=None)[source]¶
Overrides
flatsurf.geometry.categories.similarity_surfaces.SimilaritySurfaces.FiniteType.Oriented.ParentMethods.reposition_polygons()
to allow normalizing in-place.
- set_vertex_zero(label, v, in_place=False)[source]¶
Overrides
flatsurf.geometry.categories.similarity_surfaces.SimilaritySurfaces.Oriented.ParentMethods.set_vertex_zero()
to make it possible to set the zero vertex in-place.
- subdivide_polygon(p, v1, v2, test=False, new_label=None)[source]¶
Overrides
flatsurf.geometry.categories.similarity_surfaces.SimilaritySurfaces.Oriented.ParentMethods.subdivide_polygon()
to allow subdividing in-place.
- triangulate(in_place=False, label=None, relabel=None)[source]¶
Overrides
flatsurf.geometry.categories.similarity_surfaces.SimilaritySurfaces.Oriented.ParentMethods.triangulate()
to allow triangulating in-place.
- unglue(label, edge)[source]¶
Unglue the side
edge
of the polygonlabel
if it is glued.EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface, translation_surfaces sage: T = translation_surfaces.square_torus() sage: S = MutableOrientedSimilaritySurface.from_surface(T) sage: S.unglue(0, 0) sage: S.gluings() (((0, 1), (0, 3)), ((0, 3), (0, 1))) sage: S.set_immutable() sage: S Translation Surface with boundary built from a square
- class flatsurf.geometry.surface.MutableOrientedSimilaritySurface_base(base, category=None)[source]¶
Base class for surface built from Euclidean polyogns glued by orientation preserving similarities.
This provides the features of
MutableOrientedSimilaritySurface
without making a choice about how data is stored internally; it is a generic base class for other implementations of mutable surfaces.EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: from flatsurf.geometry.surface import MutableOrientedSimilaritySurface_base sage: isinstance(S, MutableOrientedSimilaritySurface_base) True
- __annotations__ = {}¶
- __module__ = 'flatsurf.geometry.surface'¶
- standardize_polygons(in_place=False)[source]¶
Replace each polygon with a new polygon which differs by translation and reindexing. The new polygon will have the property that vertex zero is the origin, and all vertices lie either in the upper half plane, or on the x-axis with non-negative x-coordinate.
This is done to the current surface if in_place=True. A mutable copy is created and returned if in_place=False (as default).
This overrides
flatsurf.geometry.categories.similarity_surfaces.SimilaritySurfaces.FiniteType.Oriented.ParentMethods.standardize_polygons()
to provide in-place standardizing of surfaces.EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface, Polygon sage: p = Polygon(vertices = ([(1,1),(2,1),(2,2),(1,2)])) sage: s = MutableOrientedSimilaritySurface(QQ) sage: s.add_polygon(p) 0 sage: s.glue((0, 0), (0, 2)) sage: s.glue((0, 1), (0, 3)) sage: s.set_root(0) sage: s.set_immutable() sage: s.standardize_polygons().polygon(0) Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)])
- triangle_flip(label, edge, in_place=False, test=None, direction=None)[source]¶
Overrides
categories.similarity_surfaces.SimilaritySurfaces.Oriented.ParentMethods.triangle_flip()
to provide in-place flipping of triangles.See that method for details.
- class flatsurf.geometry.surface.MutablePolygonalSurface(base, category=None)[source]¶
A base class for mutable surfaces that are built by gluing polygons.
EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: from flatsurf.geometry.surface import MutablePolygonalSurface sage: isinstance(S, MutablePolygonalSurface) True
- __annotations__ = {}¶
- __eq__(other)[source]¶
Return whether this surface is indistinguishable from
other
.See
_test_eq_surface()
for details on this notion of equality.EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: T = MutableOrientedSimilaritySurface(QQ) sage: S == T True sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S == T False
- __hash__()[source]¶
Return a hash value for this surface that is compatible with
__eq__()
.EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: T = MutableOrientedSimilaritySurface(QQ) sage: hash(S) == hash(T) Traceback (most recent call last): ... TypeError: cannot hash a mutable surface sage: S.set_immutable() sage: T.set_immutable() sage: hash(S) == hash(T) True
- __module__ = 'flatsurf.geometry.surface'¶
- add_polygon(polygon, label)[source]¶
Add an unglued polygon to this surface and return its label.
INPUT:
polygon
– a simple Euclidean polygonlabel
– a hashable identifier orNone
(default:None
); ifNone
an integer identifier is automatically selected
EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.add_polygon(polygons.square(), label=0) Traceback (most recent call last): ... ValueError: polygon label already present in this surface sage: S.add_polygon(polygons.square(), label='X') 'X'
- add_polygons(polygons)[source]¶
Add several polygons with automatically assigned labels at once.
EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: from flatsurf import polygons sage: S.add_polygons([polygons.square(), polygons.square()]) doctest:warning ... UserWarning: add_polygons() has been deprecated and will be removed in a future version of sage-flatsurf; use labels = [add_polygon(p) for p in polygons] instead [0, 1]
- change_base_label(label)[source]¶
This is a deprecated alias for
set_root()
.EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.change_base_label(0) doctest:warning ... UserWarning: change_base_label() has been deprecated and will be removed in a future version of sage-flatsurf; use set_root() instead
- components()[source]¶
Return the connected components as the sequence of their respective polygon labels.
EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: S.components() () sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.components() ((0,),) sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 1 sage: S.components() ((0,), (1,)) sage: S.glue((0, 0), (1, 0)) sage: S.components() ((0, 1),)
- is_mutable()[source]¶
Return whether this surface can be modified.
This implements
flatsurf.geometry.categories.topological_surfaces.TopologicalSurfaces.ParentMethods.is_mutable()
.EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: S.is_mutable() True sage: S.set_immutable() sage: S.is_mutable() False
- labels()[source]¶
Return the polygon labels in this surface.
This replaces the generic
flatsurf.geometry.categories.polygonal_surfaces.PolygonalSurfaces.ParentMethods.labels()
method with a more efficient implementation.EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: S.labels() () sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.labels() (0,)
See also
polygon()
to translate polygon labels to the corresponding polygonspolygons()
for the corresponding sequence of polygons
- polygon(label)[source]¶
Return the polygon with label
label
in this surface.This implements
flatsurf.geometry.categories.polygonal_surfaces.PolygonalSurfaces.ParentMethods.polygon()
.EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: S.polygon(0) Traceback (most recent call last): ... KeyError: 0 sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.polygon(0) Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)])
- polygons()[source]¶
Return the polygons that make up this surface.
The order the polygons are returned is guaranteed to be compatible with the order of the labels in
labels()
.This replaces the generic
flatsurf.geometry.categories.polygonal_surfaces.PolygonalSurfaces.ParentMethods.polygons()
with a more efficient implementation.EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: S.polygons() () sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.add_polygon(polygons.square()) 1 sage: S.add_polygon(polygons.square()) 2 sage: S.polygons() (Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)]), Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)]), Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)]))
See also
polygon()
to get a single polygon
- remove_polygon(label)[source]¶
Remove the polygon with label
label
from this surface (and all data associated to it.)EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.remove_polygon(0) sage: S.add_polygon(polygons.square()) 0
- roots()[source]¶
Return a label for each connected component on this surface.
This implements
flatsurf.geometry.categories.polygonal_surfaces.PolygonalSurfaces.ParentMethods.roots()
.EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: S.roots() () sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.roots() (0,) sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 1 sage: S.roots() (0, 1) sage: S.glue((0, 0), (1, 0)) sage: S.roots() (0,)
See also
- set_default_graphical_surface(graphical_surface)[source]¶
EXAMPLES:
This has been disabled because it tends to break caching:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: S.set_default_graphical_surface(S.graphical_surface()) Traceback (most recent call last): ... NotImplementedError: set_default_graphical_surface() has been removed from this version of sage-flatsurf. If you want to change the default plotting of a surface, create a subclass and override graphical_surface() instead
- set_immutable()[source]¶
Make this surface immutable.
Any mutation attempts from now on will be an error.
EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.glue((0, 0), (0, 2)) sage: S.glue((0, 1), (0, 3))
Note that declaring a surface immutable refines its category and thereby unlocks more methods that are available to such a surface:
sage: S.category() Category of finite type oriented similarity surfaces sage: old_methods = set(method for method in dir(S) if not method.startswith('_')) sage: S.set_immutable() sage: S.category() Category of connected without boundary finite type translation surfaces sage: new_methods = set(method for method in dir(S) if not method.startswith('_')) sage: new_methods - old_methods {'affine_automorphism_group', 'area', 'canonicalize', 'canonicalize_mapping', 'erase_marked_points', 'holonomy_field', 'is_veering_triangulated', 'j_invariant', 'l_infinity_delaunay_triangulation', 'minimal_translation_cover', 'normalized_coordinates', 'pyflatsurf', 'rel_deformation', 'stratum', 'veech_group', 'veering_triangulation'}
An immutable surface cannot be mutated anymore:
sage: S.remove_polygon(0) Traceback (most recent call last): ... Exception: cannot modify an immutable surface
However, the category of an immutable might be further refined as (expensive to determine) features of the surface are deduced.
- set_root(root)[source]¶
Set
root
as the label at which exploration of a connected component starts.This method can be called for connected and disconnected surfaces. In either case, it establishes
root
as the new label from which enumeration of the connected component containing it starts. If another label for this component had been set earlier, it is replaced.Note
After roots have been declared explicitly, gluing operations come at an additional cost since the root labels have to be updated sometimes. It is therefore good practice to declare the root labels after all the gluings have been established when creating a surface.
INPUT:
root
– a polygon label in this surface
EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: S.set_root(0) Traceback (most recent call last): ... ValueError: root must be a label in the surface sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.add_polygon(polygons.square()) 1 sage: S.set_root(0) sage: S.set_root(1) sage: S.roots() (0, 1)
Note that the roots get updated automatically when merging components:
sage: S.glue((0, 0), (1, 0)) sage: S.roots() (0,)
The purpose of changing the root label is to modify the order of exploration, e.g., in
labels()
:sage: S.labels() (0, 1) sage: S.set_root(1) sage: S.labels() (1, 0)
See also
set_roots()
to replace all the root labels
- set_roots(roots)[source]¶
Declare that the labels in
roots
are the labels from which their corresponding connected components should be enumerated.There must be at most one label for each connected component in
roots
. Components that have no label set explicitly will have their label chosen automatically.INPUT:
roots
– a sequence of polygon labels in this surface
EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.add_polygon(polygons.square()) 1 sage: S.add_polygon(polygons.square()) 2 sage: S.glue((0, 0), (1, 0)) sage: S.set_roots([1]) sage: S.roots() (1, 2)
Setting the roots of connected components affects their enumeration in
labels()
:sage: S.labels() (1, 0, 2) sage: S.set_roots([0, 2]) sage: S.labels() (0, 1, 2)
There must be at most one root per component:
sage: S.set_roots([0, 1, 2]) Traceback (most recent call last): ... ValueError: there must be at most one root label for each connected component
- class flatsurf.geometry.surface.OrientedSimilaritySurface(base, category=None)[source]¶
Base class for surfaces built from Euclidean polygons that are glued with orientation preserving similarities.
EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: from flatsurf.geometry.surface import OrientedSimilaritySurface sage: isinstance(S, OrientedSimilaritySurface) True
- Element¶
alias of
SurfacePoint
- __annotations__ = {}¶
- __module__ = 'flatsurf.geometry.surface'¶
- class flatsurf.geometry.surface.Polygons(surface, finite=None)[source]¶
The collection of polygons of a surface.
The polygons are returned in the same order as labels of the surface are returned by
Labels
.EXAMPLES:
sage: from flatsurf import translation_surfaces sage: C = translation_surfaces.cathedral(1, 2) sage: polygons = C.polygons() sage: from flatsurf.geometry.surface import Polygons sage: isinstance(polygons, Polygons) True
- __abstractmethods__ = frozenset({})¶
- __annotations__ = {}¶
- __iter__()[source]¶
Iterate over the polygons in the same order as
labels()
does.EXAMPLES:
sage: from flatsurf import translation_surfaces sage: C = translation_surfaces.cathedral(1, 2) sage: labels = C.labels() sage: polygons = C.polygons() sage: for entry in zip(labels, polygons): ....: print(entry) (0, Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)])) (1, Polygon(vertices=[(1, 0), (1, -2), (3/2, -5/2), (2, -2), (2, 0), (2, 1), (2, 3), (3/2, 7/2), (1, 3), (1, 1)])) (3, Polygon(vertices=[(3, 0), (7/2, -1/2), (11/2, -1/2), (6, 0), (6, 1), (11/2, 3/2), (7/2, 3/2), (3, 1)])) (2, Polygon(vertices=[(2, 0), (3, 0), (3, 1), (2, 1)]))
- __len__()[source]¶
Return the number of polygons in this surface.
EXAMPLES:
sage: from flatsurf import translation_surfaces sage: C = translation_surfaces.cathedral(1, 2) sage: polygons = C.polygons() sage: len(polygons) 4
- __module__ = 'flatsurf.geometry.surface'¶
- class flatsurf.geometry.surface.Polygons_MutableOrientedSimilaritySurface(surface)[source]¶
The collection of polygons of a
MutableOrientedSimilaritySurface
.This is a faster version of
Polygons
.EXAMPLES:
sage: from flatsurf import translation_surfaces sage: C = translation_surfaces.cathedral(1, 2) sage: polygons = C.polygons() sage: from flatsurf.geometry.surface import Polygons_MutableOrientedSimilaritySurface sage: isinstance(polygons, Polygons_MutableOrientedSimilaritySurface) True
- __abstractmethods__ = frozenset({})¶
- __annotations__ = {}¶
- __module__ = 'flatsurf.geometry.surface'¶
- class flatsurf.geometry.surface.RootedComponents_MutablePolygonalSurface(surface)[source]¶
Connected components of a
MutablePolygonalSurface
.The components are represented as a mapping that maps the root labels to the labels of the corresponding component.
This is a helper method for
MutablePolygonalSurface.components()
andMutablePolygonalSurface.roots()
.EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.add_polygon(polygons.square()) 1 sage: from flatsurf.geometry.surface import RootedComponents_MutablePolygonalSurface sage: components = RootedComponents_MutablePolygonalSurface(S)
- __abstractmethods__ = frozenset({})¶
- __annotations__ = {}¶
- __dict__ = mappingproxy({'__module__': 'flatsurf.geometry.surface', '__doc__': '\n Connected components of a :class:`MutablePolygonalSurface`.\n\n The components are represented as a mapping that maps the root labels to\n the labels of the corresponding component.\n\n This is a helper method for :meth:`MutablePolygonalSurface.components` and\n :meth:`MutablePolygonalSurface.roots`.\n\n EXAMPLES::\n\n sage: from flatsurf import MutableOrientedSimilaritySurface\n sage: S = MutableOrientedSimilaritySurface(QQ)\n\n sage: from flatsurf import polygons\n sage: S.add_polygon(polygons.square())\n 0\n sage: S.add_polygon(polygons.square())\n 1\n\n sage: from flatsurf.geometry.surface import RootedComponents_MutablePolygonalSurface\n sage: components = RootedComponents_MutablePolygonalSurface(S)\n\n ', '__init__': <function RootedComponents_MutablePolygonalSurface.__init__>, '__getitem__': <function RootedComponents_MutablePolygonalSurface.__getitem__>, '__iter__': <function RootedComponents_MutablePolygonalSurface.__iter__>, '__len__': <function RootedComponents_MutablePolygonalSurface.__len__>, '__dict__': <attribute '__dict__' of 'RootedComponents_MutablePolygonalSurface' objects>, '__weakref__': <attribute '__weakref__' of 'RootedComponents_MutablePolygonalSurface' objects>, '__abstractmethods__': frozenset(), '_abc_impl': <_abc._abc_data object>, '__annotations__': {}})¶
- __getitem__(root)[source]¶
Return the labels of the connected component rooted at the label
root
.EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.add_polygon(polygons.square()) 1 sage: S.glue((0, 0), (1, 0)) sage: from flatsurf.geometry.surface import RootedComponents_MutablePolygonalSurface sage: components = RootedComponents_MutablePolygonalSurface(S) sage: components[0] (0, 1)
- __iter__()[source]¶
Iterate over the keys of this mapping, i.e., the root labels of the connected components.
EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.add_polygon(polygons.square()) 1 sage: S.glue((0, 0), (1, 0)) sage: from flatsurf.geometry.surface import RootedComponents_MutablePolygonalSurface sage: components = RootedComponents_MutablePolygonalSurface(S) sage: list(components) [0]
- __len__()[source]¶
Return the number of connected components of this surface.
EXAMPLES:
sage: from flatsurf import MutableOrientedSimilaritySurface sage: S = MutableOrientedSimilaritySurface(QQ) sage: from flatsurf import polygons sage: S.add_polygon(polygons.square()) 0 sage: S.add_polygon(polygons.square()) 1 sage: S.glue((0, 0), (1, 0)) sage: from flatsurf.geometry.surface import RootedComponents_MutablePolygonalSurface sage: components = RootedComponents_MutablePolygonalSurface(S) sage: len(components) 1
- __module__ = 'flatsurf.geometry.surface'¶
- __weakref__¶
list of weak references to the object
- class flatsurf.geometry.surface.Surface_base[source]¶
A base class for all surfaces in sage-flatsurf.
This class patches bits of the category framework in SageMath that assume that all parent structures are immutable.
EXAMPLES:
sage: from flatsurf import translation_surfaces sage: S = translation_surfaces.square_torus() sage: from flatsurf.geometry.surface import Surface_base sage: isinstance(S, Surface_base) True
- __annotations__ = {}¶
- __dict__ = mappingproxy({'__module__': 'flatsurf.geometry.surface', '__doc__': '\n A base class for all surfaces in sage-flatsurf.\n\n This class patches bits of the category framework in SageMath that assume\n that all parent structures are immutable.\n\n EXAMPLES::\n\n sage: from flatsurf import translation_surfaces\n sage: S = translation_surfaces.square_torus()\n\n sage: from flatsurf.geometry.surface import Surface_base\n sage: isinstance(S, Surface_base)\n True\n\n ', '_refine_category_': <function Surface_base._refine_category_>, 'an_element': <function Surface_base.an_element>, '__dict__': <attribute '__dict__' of 'Surface_base' objects>, '__annotations__': {}})¶
- __module__ = 'flatsurf.geometry.surface'¶