euclidean_polygons_with_angles
¶
The category of polygons in the real plane with fixed rational angles.
This module provides a common structure for all polygons with certain fixed angles.
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 polygons.
EXAMPLES:
The category of rectangles:
sage: from flatsurf.geometry.categories import EuclideanPolygons
sage: C = EuclideanPolygons(QQ).WithAngles([1, 1, 1, 1])
It is often tedious to create this category manually, since you need to determine a base ring that can describe the coordinates of polygons with such angles:
sage: C = EuclideanPolygons(QQ).WithAngles([1, 1, 1])
sage: C.slopes()
Traceback (most recent call last):
...
TypeError: Unable to coerce c to a rational
sage: C = EuclideanPolygons(AA).WithAngles([1, 1, 1])
sage: C.slopes()
[(1, 0), (-0.5773502691896258?, 1), (-0.5773502691896258?, -1)]
Instead, we can use EuclideanPolygonsWithAngles()
to create this category
over a minimal number field:
sage: from flatsurf import EuclideanPolygonsWithAngles
sage: C = EuclideanPolygonsWithAngles([1, 1, 1])
sage: C.slopes()
[(1, 0), (-c, 3), (-c, -3)]
The category of polygons is automatically determined when using
Polygon()
:
sage: from flatsurf import Polygon
sage: p = Polygon(angles=(1, 1, 1))
sage: p.category()
Category of convex simple euclidean equilateral triangles over Number Field in c with defining polynomial x^2 - 3 with c = 1.732050807568878?
However, it can be very costly to determine that a polygon is rational and what its actual angles are (the “equilateral” in the previous example). Therefore, the category might get refined once these aspects have been determined:
sage: p = Polygon(edges=[(1, 0), (0, 1), (-1, 0), (0, -1)])
sage: p.category()
Category of convex simple euclidean polygons over Rational Field
sage: p.is_rational()
True
sage: p.category()
Category of rational convex simple euclidean polygons over Rational Field
sage: p.angles()
(1/4, 1/4, 1/4, 1/4)
sage: p.category()
Category of convex simple euclidean rectangles over Rational Field
Note that SageMath applies the same strategy when determining whether the integers modulo N are a field:
sage: K = Zmod(1361)
sage: K.category()
Join of Category of finite commutative rings and Category of subquotients of monoids and Category of quotients of semigroups and Category of finite enumerated sets
sage: K.is_field()
True
sage: K.category()
Join of Category of finite enumerated fields and Category of subquotients of monoids and Category of quotients of semigroups
- class flatsurf.geometry.categories.euclidean_polygons_with_angles.EuclideanPolygonsWithAngles(base_ring, angles)[source]¶
The category of euclidean polygons with fixed rational angles.
EXAMPLES:
sage: from flatsurf.geometry.categories import EuclideanPolygons sage: C = EuclideanPolygons(QQ).WithAngles([1, 1, 1, 1])
- class ParentMethods[source]¶
Provides methods available to all polygons with known angles.
If you want to add functionality to all such polygons, you probably want to put it here.
- angle(e, numerical=None, assume_rational=None)[source]¶
Return the angle at the beginning of the start point of the edge
e
.EXAMPLES:
sage: from flatsurf.geometry.polygon import polygons sage: polygons.square().angle(0) 1/4 sage: polygons.regular_ngon(8).angle(0) 3/8 sage: from flatsurf import Polygon sage: T = Polygon(vertices=[(0,0), (3,1), (1,5)]) sage: [T.angle(i, numerical=True) for i in range(3)] # abs tol 1e-13 [0.16737532973071603, 0.22741638234956674, 0.10520828791971722] sage: sum(T.angle(i, numerical=True) for i in range(3)) # abs tol 1e-13 0.5
- is_convex(strict=False)[source]¶
Return whether this is a convex polygon.
INPUT:
strict
– whether to check for strict convexity, i.e., a polygon with a π angle is not considered convex.
EXAMPLES:
sage: from flatsurf import polygons sage: S = polygons.square() sage: S.is_convex() True sage: S.is_convex(strict=True) True
- class Simple(base_category)[source]¶
The subcategory of simple Euclidean polygons with prescribed angles.
EXAMPLES:
sage: from flatsurf.geometry.categories import EuclideanPolygons sage: EuclideanPolygons(QQ).WithAngles([1, 1, 1, 1]).Simple() Category of simple euclidean rectangles over Rational Field
- class SubcategoryMethods[source]¶
- an_element()[source]¶
Return a polygon in this category.
Since currently polygons must not be self-intersecting, the construction used might fail.
EXAMPLES:
sage: from flatsurf import EuclideanPolygonsWithAngles sage: EuclideanPolygonsWithAngles(4, 3, 4, 4, 3, 4).an_element() Polygon(vertices=[(0, 0), (1/22*c + 1, 0), (9*c^9 + 1/2*c^8 - 88*c^7 - 9/2*c^6 + 297*c^5 + 27/2*c^4 - 396*c^3 - 15*c^2 + 3631/22*c + 11/2, 1/2*c + 11), (16*c^9 + c^8 - 154*c^7 - 9*c^6 + 506*c^5 + 27*c^4 - 638*c^3 - 30*c^2 + 4841/22*c + 9, c + 22), (16*c^9 + c^8 - 154*c^7 - 9*c^6 + 506*c^5 + 27*c^4 - 638*c^3 - 30*c^2 + 220*c + 8, c + 22), (7*c^9 + 1/2*c^8 - 66*c^7 - 9/2*c^6 + 209*c^5 + 27/2*c^4 - 242*c^3 - 15*c^2 + 55*c + 7/2, 1/2*c + 11)])
- angles(integral=False)[source]¶
Return the interior angles of this polygon as multiples of 2π.
INPUT:
integral
– a boolean (default:False
); whether to return the angles not as multiples of 2π but rescaled so that they have no denominators.
EXAMPLES:
sage: from flatsurf import EuclideanPolygonsWithAngles sage: E = EuclideanPolygonsWithAngles(1, 1, 1, 2, 6) sage: E.angles() (3/22, 3/22, 3/22, 3/11, 9/11)
When
integral
is set, the output is scaled to eliminate denominators:sage: E.angles(integral=True) (1, 1, 1, 2, 6)
- billiard_unfolding_angles(cover_type='translation')[source]¶
Return the angles of the unfolding rational, half-translation or translation surface.
INPUT:
cover_type
(optional, default"translation"
) - either"rational"
,"half-translation"
or"translation"
EXAMPLES:
sage: from flatsurf import EuclideanPolygonsWithAngles sage: E = EuclideanPolygonsWithAngles(1, 2, 5) sage: E.billiard_unfolding_angles(cover_type="rational") {1/8: 1, 1/4: 1, 5/8: 1} sage: (1/8 - 1) + (1/4 - 1) + (5/8 - 1) # Euler characteristic (of the sphere) -2 sage: E.billiard_unfolding_angles(cover_type="half-translation") {1/2: 3, 5/2: 1} sage: E.billiard_unfolding_angles(cover_type="translation") {1: 3, 5: 1} sage: E = EuclideanPolygonsWithAngles(1, 3, 1, 7) sage: E.billiard_unfolding_angles(cover_type="rational") {1/6: 2, 1/2: 1, 7/6: 1} sage: 2 * (1/6 - 1) + (1/2 - 1) + (7/6 - 1) # Euler characteristic -2 sage: E.billiard_unfolding_angles(cover_type="half-translation") {1/2: 5, 7/2: 1} sage: E.billiard_unfolding_angles(cover_type="translation") {1: 5, 7: 1} sage: E = EuclideanPolygonsWithAngles(1, 3, 5, 7) sage: E.billiard_unfolding_angles(cover_type="rational") {1/8: 1, 3/8: 1, 5/8: 1, 7/8: 1} sage: (1/8 - 1) + (3/8 - 1) + (5/8 - 1) + (7/8 - 1) # Euler characteristic -2 sage: E.billiard_unfolding_angles(cover_type="half-translation") {1/2: 1, 3/2: 1, 5/2: 1, 7/2: 1} sage: E.billiard_unfolding_angles(cover_type="translation") {1: 1, 3: 1, 5: 1, 7: 1} sage: E = EuclideanPolygonsWithAngles(1, 2, 8) sage: E.billiard_unfolding_angles(cover_type="rational") {1/11: 1, 2/11: 1, 8/11: 1} sage: (1/11 - 1) + (2/11 - 1) + (8/11 - 1) # Euler characteristic -2 sage: E.billiard_unfolding_angles(cover_type="half-translation") {1: 1, 2: 1, 8: 1} sage: E.billiard_unfolding_angles(cover_type="translation") {1: 1, 2: 1, 8: 1}
- billiard_unfolding_stratum(cover_type='translation', marked_points=False)[source]¶
Return the stratum of quadratic or Abelian differential obtained by unfolding a billiard in a polygon of this equiangular family.
INPUT:
cover_type
(optional, default"translation"
) - either"rational"
,"half-translation"
or"translation"
marked_poins
(optional, defaultFalse
) - whether the stratum should have regular marked points
EXAMPLES:
sage: from flatsurf import EuclideanPolygonsWithAngles, similarity_surfaces sage: E = EuclideanPolygonsWithAngles(1, 2, 5) sage: E.billiard_unfolding_stratum("half-translation") Q_1(3, -1^3) sage: E.billiard_unfolding_stratum("translation") H_3(4) sage: E.billiard_unfolding_stratum("half-translation", True) Q_1(3, -1^3) sage: E.billiard_unfolding_stratum("translation", True) H_3(4, 0^3) sage: E = EuclideanPolygonsWithAngles(1, 3, 1, 7) sage: E.billiard_unfolding_stratum("half-translation") Q_1(5, -1^5) sage: E.billiard_unfolding_stratum("translation") H_4(6) sage: E.billiard_unfolding_stratum("half-translation", True) Q_1(5, -1^5) sage: E.billiard_unfolding_stratum("translation", True) H_4(6, 0^5) sage: P = E.an_element() sage: S = similarity_surfaces.billiard(P) sage: S.minimal_cover("half-translation").stratum() Q_1(5, -1^5) sage: S.minimal_cover("translation").stratum() H_4(6, 0^5) sage: E = EuclideanPolygonsWithAngles(1, 3, 5, 7) sage: E.billiard_unfolding_stratum("half-translation") Q_3(5, 3, 1, -1) sage: E.billiard_unfolding_stratum("translation") H_7(6, 4, 2) sage: P = E.an_element() sage: S = similarity_surfaces.billiard(P) sage: S.minimal_cover("half-translation").stratum() Q_3(5, 3, 1, -1) sage: S.minimal_cover("translation").stratum() H_7(6, 4, 2, 0) sage: E = EuclideanPolygonsWithAngles(1, 2, 8) sage: E.billiard_unfolding_stratum("half-translation") H_5(7, 1) sage: E.billiard_unfolding_stratum("translation") H_5(7, 1) sage: E.billiard_unfolding_stratum("half-translation", True) H_5(7, 1, 0) sage: E.billiard_unfolding_stratum("translation", True) H_5(7, 1, 0) sage: E = EuclideanPolygonsWithAngles(9, 6, 3, 2) sage: p = E.an_element() sage: B = similarity_surfaces.billiard(p) sage: B.minimal_cover("half-translation").stratum() Q_4(7, 4, 1, 0) sage: E.billiard_unfolding_stratum("half-translation", True) Q_4(7, 4, 1, 0) sage: B.minimal_cover("translation").stratum() H_8(8, 2^3, 0^2) sage: E.billiard_unfolding_stratum("translation", True) H_8(8, 2^3, 0^2)
- billiard_unfolding_stratum_dimension(cover_type='translation', marked_points=False)[source]¶
Return the dimension of the stratum of quadratic or Abelian differential obtained by unfolding a billiard in a polygon of this equiangular family.
INPUT:
cover_type
(optional, default"translation"
) - either"rational"
,"half-translation"
or"translation"
marked_poins
(optional, defaultFalse
) - whether the stratum should have marked regular points
EXAMPLES:
sage: from flatsurf import EuclideanPolygonsWithAngles sage: E = EuclideanPolygonsWithAngles(1, 1, 1) sage: E.billiard_unfolding_stratum_dimension("half-translation") 2 sage: E.billiard_unfolding_stratum_dimension("translation") 2 sage: E.billiard_unfolding_stratum_dimension("half-translation", True) 4 sage: E.billiard_unfolding_stratum_dimension("translation", True) 4 sage: E = EuclideanPolygonsWithAngles(1, 2, 5) sage: E.billiard_unfolding_stratum_dimension("half-translation") 4 sage: E.billiard_unfolding_stratum("half-translation").dimension() 4 sage: E.billiard_unfolding_stratum_dimension(cover_type="translation") 6 sage: E.billiard_unfolding_stratum("translation").dimension() 6 sage: E.billiard_unfolding_stratum_dimension("translation", True) 9 sage: E.billiard_unfolding_stratum("translation", True).dimension() 9 sage: E = EuclideanPolygonsWithAngles(1, 3, 5) sage: E.billiard_unfolding_stratum_dimension("half-translation") 6 sage: E.billiard_unfolding_stratum("half-translation").dimension() 6 sage: E.billiard_unfolding_stratum_dimension("translation") 6 sage: E.billiard_unfolding_stratum("translation").dimension() 6 sage: E = EuclideanPolygonsWithAngles(1, 3, 1, 7) sage: E.billiard_unfolding_stratum_dimension("half-translation") 6 sage: E = EuclideanPolygonsWithAngles(1, 3, 5, 7) sage: E.billiard_unfolding_stratum_dimension("half-translation") 8 sage: E = EuclideanPolygonsWithAngles(1, 2, 8) sage: E.billiard_unfolding_stratum_dimension() 11 sage: E.billiard_unfolding_stratum().dimension() 11 sage: E.billiard_unfolding_stratum_dimension(marked_points=True) 12 sage: E.billiard_unfolding_stratum(marked_points=True).dimension() 12
- convexity()[source]¶
EXAMPLES:
sage: from flatsurf import EuclideanPolygonsWithAngles sage: EuclideanPolygonsWithAngles(1, 2, 5).convexity() doctest:warning ... UserWarning: convexity() has been deprecated and will be removed in a future version of sage-flatsurf; use is_convex() instead True sage: EuclideanPolygonsWithAngles(2, 2, 3, 13).convexity() False
- is_convex(strict=False)[source]¶
Return whether the polygons in this category are convex.
INPUT:
strict
– a boolean (default:False
); whether only to consider polygons convex if all angles are <π.
EXAMPLES:
sage: from flatsurf import EuclideanPolygonsWithAngles sage: EuclideanPolygonsWithAngles(1, 2, 5).is_convex() True sage: EuclideanPolygonsWithAngles(2, 2, 3, 13).is_convex() False
sage: E = EuclideanPolygonsWithAngles([1, 1, 1, 1, 2]) sage: E.angles() (1/4, 1/4, 1/4, 1/4, 1/2) sage: E.is_convex(strict=False) True sage: E.is_convex(strict=True) False
- lengths_polytope()[source]¶
Return the polytope parametrizing the admissible vectors data.
This polytope parametrizes the tangent space to the set of these equiangular polygons. Be careful that even though the lengths are admissible, they may not define a polygon without intersection.
EXAMPLES:
sage: from flatsurf import EuclideanPolygonsWithAngles sage: EuclideanPolygonsWithAngles(1, 2, 1, 2).lengths_polytope() A 2-dimensional polyhedron in (Number Field in c with defining polynomial x^2 - 3 with c = 1.732050807568878?)^4 defined as the convex hull of 1 vertex and 2 rays
- random_element(ring=None, **kwds)[source]¶
Return a random polygon in this category.
EXAMPLES:
sage: from flatsurf import EuclideanPolygonsWithAngles sage: EuclideanPolygonsWithAngles(1, 1, 1, 2, 5).random_element() Polygon(vertices=[(0, 0), ...]) sage: EuclideanPolygonsWithAngles(1,1,1,15,15,15).random_element() Polygon(vertices=[(0, 0), ...]) sage: EuclideanPolygonsWithAngles(1,15,1,15,1,15).random_element() Polygon(vertices=[(0, 0), ...])
- slopes(e0=(1, 0))[source]¶
Return the slopes of the edges as a list of vectors.
INPUT:
e0
– the first slope returned (default:(1, 0)
)
EXAMPLES:
sage: from flatsurf import EuclideanPolygonsWithAngles sage: EuclideanPolygonsWithAngles(1, 2, 1, 2).slopes() [(1, 0), (c, 3), (-1, 0), (-c, -3)]
- strict_convexity()[source]¶
EXAMPLES:
sage: from flatsurf import EuclideanPolygonsWithAngles sage: E = EuclideanPolygonsWithAngles([1, 1, 1, 1, 2]) sage: E.angles() (1/4, 1/4, 1/4, 1/4, 1/2) sage: E.convexity() True sage: E.strict_convexity() doctest:warning ... UserWarning: strict_convexity() has been deprecated and will be removed in a future version of sage-flatsurf; use is_convex(strict=True) instead False
- super_categories()[source]¶
Return the other categories such polygons are automatically members of, namely, the category of rational euclidean polygons polygons.
EXAMPLES:
sage: from flatsurf.geometry.categories import EuclideanPolygons sage: C = EuclideanPolygons(QQ).WithAngles([1, 1, 1, 1]) sage: C.super_categories() [Category of rational euclidean polygons over Rational Field]