polygonal_surfaces#

The category of surfaces built from polygons.

This module provides shared functionality for all surfaces in sage-flatsurf that are built from polygons (such as Euclidean polygons or hyperbolic polygons.)

See flatsurf.geometry.categories for a general description of the category framework in sage-flatsurf.

Normally, you won’t create this (or any other) category directly. The correct category is automatically determined for immutable surfaces.

EXAMPLES:

sage: from flatsurf import MutableOrientedSimilaritySurface
sage: C = MutableOrientedSimilaritySurface(QQ).category()

sage: from flatsurf.geometry.categories import PolygonalSurfaces
sage: C.is_subcategory(PolygonalSurfaces())
True
class flatsurf.geometry.categories.polygonal_surfaces.PolygonalSurfaces[source]#

The category of surfaces built by gluing polygons defined in some space such as the real plane (see euclidean_polygonal_surfaces.)

EXAMPLES:

sage: from flatsurf.geometry.categories import PolygonalSurfaces
sage: PolygonalSurfaces()
Category of polygonal surfaces
class FiniteType(base_category)[source]#

The axiom satisfied by surfaces built from finitely many polygons.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: 'FiniteType' in S.category().axioms()
True
class Connected(base_category)[source]#

The axiom satisfied by connected surfaces built from finitely many polygons.

EXAMPLES:

sage: from flatsurf.geometry.categories import PolygonalSurfaces
sage: PolygonalSurfaces().FiniteType().Connected()
Category of connected finite type polygonal surfaces
class ParentMethods[source]#

Provides methods available to all connected surfaces built from finitely many polygons.

If you want to add functionality for such surfaces you most likely want to put it here.

class InfiniteType(*args, **kwargs)[source]#

The axiom satisfied by surfaces that are built from finitely and infinitely many polygons at the same time.

This axiom does not exist and it is an error to create it.

class Oriented(base_category)[source]#

The axiom satisfied by orientable surfaces with an orientation which is compatible with the orientation of the ambient space of the finitely many polygons that define the surface (assuming that that ambient space is orientable.)

EXAMPLES:

sage: from flatsurf.geometry.categories import PolygonalSurfaces
sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.octagon_and_squares()
sage: S.category().is_subcategory(PolygonalSurfaces().FiniteType().Oriented())
True
class ParentMethods[source]#

Provides methods available to all surfaces built from finitely many oriented polygons.

If you want to add functionality for such surfaces you most likely want to put it here.

euler_characteristic()[source]#

Return the Euler characteristic of this surface.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.octagon_and_squares()
sage: S.euler_characteristic()
-4
class ParentMethods[source]#

Provides methods available to all surfaces built from finitely many polygons.

If you want to add functionality for such surfaces you most likely want to put it here.

is_finite_type()[source]#

Return whether this surface is built from finitely many polygons.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.is_finite_type()
True
is_triangulated()[source]#

Return whether this surfaces is built from triangles.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.is_triangulated()
False
is_with_boundary()[source]#

Return whether this surface has a boundary, i.e., unglued polygon edges.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.is_with_boundary()
False
vertices()[source]#

Return the equivalence classes of the vertices of the polygons that make up this surface.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.vertices()
{Vertex 0 of polygon 0}

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.regular_octagon()
sage: S.vertices()
{Vertex 0 of polygon 0}
extra_super_categories()[source]#

Return the categories that surfaces built from finitely many polygons are additionally contained in; namely such a surface is a compact space.

EXAMPLES:

sage: from flatsurf.geometry.categories import PolygonalSurfaces
sage: PolygonalSurfaces().FiniteType().extra_super_categories()
(Category of compact topological spaces,)
class InfiniteType(base_category)[source]#

The axiom satisfied by surfaces built from infinitely many polygons.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.infinite_staircase()
sage: 'InfiniteType' in S.category().axioms()
True
class ParentMethods[source]#

Provides methods available to all surfaces built from infinitely many polygons.

If you want to add functionality for such surfaces you most likely want to put it here.

is_finite_type()[source]#

Return whether this surfaces has been built from finitely many polygons which it has not.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.infinite_staircase()
sage: S.is_finite_type()
False
class Oriented(base_category)[source]#

The axiom satisfied by orientable surfaces with an orientation which is compatible with the orientation of the ambient space of the polygons (assuming that that ambient space is orientable.)

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.infinite_staircase()
sage: 'Oriented' in S.category().axioms()
True
class WithoutBoundary(base_category)[source]#

The axiom satisfied by oriented surfaces built from polygons that have no unglued polygon edges.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.infinite_staircase()
sage: from flatsurf.geometry.categories import PolygonalSurfaces
sage: S.category().is_subcategory(PolygonalSurfaces().Oriented().WithoutBoundary())
True
class Connected(base_category)[source]#

The axiom satisfied by oriented connected surfaces built from polygons that have no unglued polygon edges.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.infinite_staircase()
sage: from flatsurf.geometry.categories import PolygonalSurfaces
sage: S.category().is_subcategory(PolygonalSurfaces().Oriented().WithoutBoundary().Connected())
True
class ParentMethods[source]#

Provides methods available to all oriented connected surfaces built from polygons without unglued edges.

If you want to add functionality for such surfaces you most likely want to put it here.

genus()[source]#

Return the genus of this surface.

ALGORITHM:

We deduce the genus from the Euler characteristic.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: translation_surfaces.octagon_and_squares().genus()
3

This method might not be functional if the Euler characteristic has not been implemented for the surface:

sage: S = translation_surfaces.infinite_staircase()
sage: S.genus()
Traceback (most recent call last):
...
AttributeError: ... has no attribute 'euler_characteristic'...
extra_super_categories()[source]#

Return the axioms that are automatically satisfied by a surfaces which is oriented, namely, that such a surface is orientable.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.infinite_staircase()
sage: 'Orientable' in S.category().axioms()
True
class ParentMethods[source]#

Provides methods available to all surfaces that are built from polygons.

If you want to add functionality for such surfaces you most likely want to put it here.

base_label()[source]#

Return the polygon label from which iteration by labels() should start.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.infinite_staircase()
sage: S.base_label()
doctest:warning
...
UserWarning: base_label() has been deprecated and will be removed in a future version of sage-flatsurf; use root() instead for connected surfaces and roots() in general
0
component(root)[source]#

Return the labels contained in the connected component containing the label root.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.component(0)
(0,)
components()[source]#

Return the connected components that make up this surface.

OUTPUT:

A sequence of connected components where each component is in turn a sequence of the polygon labels contained in that component.

EXAMPLES:

sage: from flatsurf import polygons, MutableOrientedSimilaritySurface
sage: S = MutableOrientedSimilaritySurface(QQ)
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.components()
((0, 1), (2,))
edge_gluing_iterator()[source]#

Iterate over the ordered pairs of edges being glued.

edge_iterator(gluings=False)[source]#

Iterate over the edges of polygons, which are pairs (l,e) where l is a polygon label, 0 <= e < N and N is the number of edges of the polygon with label l.

edges()[source]#

Return the edges of the polygons that make up this surface as pairs (polygon label, edge index).

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.edges()
((0, 0), (0, 1), (0, 2), (0, 3))
sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.infinite_staircase()
sage: S.edges()
((0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (-1, 0), (-1, 1), (-1, 2), (-1, 3), (2, 0), (2, 1), (2, 2), (2, 3), …)
gluings()[source]#

Return the pairs of edges being glued to each other.

Each gluing is reported as a pair of pairs (polygon label, edge index) and (glued polygon label, glued edge index).

Note that each gluing is reported twice (unless it is a self-gluing.)

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.square_torus()
sage: S.gluings()
(((0, 0), (0, 2)), ((0, 1), (0, 3)), ((0, 2), (0, 0)), ((0, 3), (0, 1)))

A surface with only self-gluings:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.gluings()
(((0, 0), (0, 0)), ((0, 1), (0, 1)), ((0, 2), (0, 2)), ((0, 3), (0, 3)))
is_connected()[source]#

Return whether this surface is connected.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.is_connected()
True
is_finite()[source]#

Return whether this surface is constructed from finitely many polygons.

Note

The semantics of this function clash with the notion of finite sets inherited from the category of sets. Therefore is_finite_type() should be used instead.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.is_finite_type()
True
is_finite_type()[source]#

Return whether this surface is constructed from finitely many polygons.

Note

This method is used to determine whether this surface satisfies the FiniteType axiom or the InfiniteType axiom. Surfaces can override this method to perform specialized logic, see the note in flatsurf.geometry.categories for performance considerations.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.is_finite_type()
True
is_triangulated()[source]#

Return whether this surface is built from triangles.

Surfaces of infinite type should override this method.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.infinite_staircase()
sage: S.is_triangulated()
False
label_iterator(polygons=False)[source]#
label_polygon_iterator()[source]#

Iterate over pairs (label, polygon).

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: print(list(S.label_polygon_iterator()))
doctest:warning
...
UserWarning: label_polygon_iterator() has been deprecated and will be removed from a future version of sage-flatsurf; use zip(labels(), polygons()) instead
[(0, Polygon(vertices=[(0, 0), (2, 0), (1, 4), (0, 5)]))]
sage: print(list(zip(S.labels(), S.polygons())))
[(0, Polygon(vertices=[(0, 0), (2, 0), (1, 4), (0, 5)]))]
labels()[source]#

Return the labels used to enumerate the polygons that make up this surface.

The labels are returned in a breadth first search order starting at the base_label(). This order is compatible with the order in which polygons are returned by polygons().

Note

The generic implementation of this method returns a collection that is very slow at computing its length and deciding containment. To speed things up it is recommended to override this method.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.labels()
(0,)
sage: from flatsurf import translation_surfaces
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, …)
num_edges()[source]#

Return the total number of edges of all polygons used.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.num_edges()
doctest:warning
...
UserWarning: num_edges() has been deprecated and will be removed from a future version of sage-flatsurf; use sum(len(p.vertices()) for p in polygons()) instead
4
num_polygons()[source]#

Return the number of polygons that make up this surface.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.num_polygons()
doctest:warning
...
UserWarning: num_polygons() is deprecated and will be removed in a future version of sage-flatsurf; use len(polygons()) instead (and is_finite_type() for potentially infinite surfaces.)
1
sage: len(S.polygons())
1
sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.infinite_staircase()
sage: S.num_polygons()
+Infinity
sage: S.is_finite_type()
False
opposite_edge(label, edge)[source]#

Return the polygon label and edge that is glued to the edge of the polygon with label.

INPUT:

  • label – one of the labels included in labels()

  • edge – a non-negative integer to specify an edge (the edges of a polygon are numbered starting from zero.)

OUTPUT:

A tuple (label, edge) with the semantics as in the input.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.opposite_edge(0, 0)
(0, 0)
polygon(label)[source]#

Return the polygon with label.

INPUT:

  • label – one of the labels included in labels()

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.polygon(0)
Polygon(vertices=[(0, 0), (2, 0), (1, 4), (0, 5)])
polygons()[source]#

Return the polygons that make up this surface (in the same order as the labels are returned by labels())

Note

Unlike with labels(), this method should usually not be overridden. Things will be fast if labels() is fast.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.polygons()
(Polygon(vertices=[(0, 0), (2, 0), (1, 4), (0, 5)]),)
sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.infinite_staircase()
sage: S.polygons()
(Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)]), Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)]), ...)
refined_category()[source]#

Return the smallest subcategory that this surface is in by consulting which edges are glued to each other.

Note that this does not take into account how the edges are glued to each other exactly (e.g., by which similarity) since at this level (i.e., without knowing about the space in which the polygons live) the gluing is just described combinatorially.

EXAMPLES:

sage: from flatsurf import MutableOrientedSimilaritySurface, polygons
sage: S = MutableOrientedSimilaritySurface(QQ)

sage: from flatsurf import polygons
sage: S.add_polygon(polygons.square(), label=0)
0
sage: S.refined_category()
Category of connected with boundary finite type translation surfaces

sage: S.glue((0, 0), (0, 2))
sage: S.glue((0, 1), (0, 3))
sage: S.refined_category()
Category of connected without boundary finite type translation surfaces
root()[source]#

Return the polygon label from which iteration by labels() should start on this connected surface.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.infinite_staircase()
sage: S.root()
0

When there are multiple connected components, roots() must be used instead:

sage: from flatsurf import MutableOrientedSimilaritySurface, polygons
sage: S = MutableOrientedSimilaritySurface(QQ)
sage: S.add_polygon(polygons.square())
0
sage: S.add_polygon(polygons.square())
1

sage: S.root()
Traceback (most recent call last):
...
Exception: surface has more than one root label, use roots() instead
sage: S.roots()
(0, 1)
roots()[source]#

Return root labels for the polygons forming the connected components of this surface.

A root label is just any of the labels() of the surface. However, the iteration of labels() starts from those root labels so for some surfaces they might have been specifically chosen.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: S.roots()
(0,)
walker()[source]#

Return an iterable that walks the labels of the surface.

EXAMPLES:

sage: from flatsurf import Polygon, similarity_surfaces
sage: P = Polygon(vertices=[(0,0), (2,0), (1,4), (0,5)])
sage: S = similarity_surfaces.self_glued_polygon(P)
sage: walker = S.walker()
doctest:warning
...
UserWarning: walker() is deprecated and will be removed from a future version of sage-flatsurf; use labels() instead.
sage: list(walker)
[0]
class SubcategoryMethods[source]#
FiniteType()[source]#

Return the subcategory of surfaces built from finitely many polygons.

EXAMPLES:

sage: from flatsurf.geometry.categories import PolygonalSurfaces
sage: PolygonalSurfaces().FiniteType()
Category of finite type polygonal surfaces
InfiniteType()[source]#

Return the subcategory of surfaces built from infinitely many polygons.

EXAMPLES:

sage: from flatsurf.geometry.categories import PolygonalSurfaces
sage: PolygonalSurfaces().InfiniteType()
Category of infinite type polygonal surfaces
Oriented()[source]#

Return the subcategory of surfaces with an orientation that is inherited from the polygons that it is built from.

This assumes that the ambient space of the polygons is orientable.

EXAMPLES:

sage: from flatsurf.geometry.categories import PolygonalSurfaces
sage: PolygonalSurfaces().Oriented()
Category of oriented polygonal surfaces
class WithoutBoundary(base_category)[source]#

The axiom satisfied by surfaces built from polygons without any unglued edges.

EXAMPLES:

sage: from flatsurf import translation_surfaces
sage: S = translation_surfaces.infinite_staircase()
sage: from flatsurf.geometry.categories import PolygonalSurfaces
sage: S.category().is_subcategory(PolygonalSurfaces().WithoutBoundary())
True
class ParentMethods[source]#

Provides methods available to all surfaces that are built from polygons without unglued edges.

If you want to add functionality for such surfaces you most likely want to put it here.

super_categories()[source]#

Return the categories that a polygonal surface is always also a member of.

EXAMPLES:

sage: from flatsurf.geometry.categories import PolygonalSurfaces
sage: PolygonalSurfaces().super_categories()
[Category of topological surfaces]