polygon
¶
Polygons embedded in the plane \(\mathbb{R}^2\).
The emphasis is mostly on convex polygons but there is some limited support for non-convex polygons.
EXAMPLES:
sage: from flatsurf.geometry.polygon import Polygon
sage: K.<sqrt2> = NumberField(x^2 - 2, embedding=AA(2).sqrt())
sage: p = Polygon(edges=[(1,0), (-sqrt2,1+sqrt2), (sqrt2-1,-1-sqrt2)])
sage: p
Polygon(vertices=[(0, 0), (1, 0), (-sqrt2 + 1, sqrt2 + 1)])
sage: M = MatrixSpace(K,2)
sage: m = M([[1,1+sqrt2],[0,1]])
sage: m * p
Polygon(vertices=[(0, 0), (1, 0), (sqrt2 + 4, sqrt2 + 1)])
- flatsurf.geometry.polygon.ConvexPolygons(base_ring)[source]¶
EXAMPLES:
sage: from flatsurf import ConvexPolygons sage: P = ConvexPolygons(QQ) doctest:warning ... UserWarning: ConvexPolygons() has been deprecated and will be removed from a future version of sage-flatsurf; use Polygon() to create polygons. If you really need the category of convex polygons over a ring use EuclideanPolygons(ring).Simple().Convex() instead. sage: P(vertices=[(0, 0), (1, 0), (0, 1)]) doctest:warning ... UserWarning: ConvexPolygons(…)(…) has been deprecated and will be removed in a future version of sage-flatsurf; use Polygon() instead Polygon(vertices=[(0, 0), (1, 0), (0, 1)])
- flatsurf.geometry.polygon.EquiangularPolygons(*angles, **kwds)[source]¶
EXAMPLES:
sage: from flatsurf import EquiangularPolygons sage: EquiangularPolygons(1, 1, 1) doctest:warning ... UserWarning: EquiangularPolygons() has been deprecated and will be removed in a future version of sage-flatsurf; use EuclideanPolygonsWithAngles() instead Category of simple euclidean equilateral triangles over Number Field in c with defining polynomial x^2 - 3 with c = 1.732050807568878?
- class flatsurf.geometry.polygon.EuclideanPolygon(base_ring, vertices, category=None)[source]¶
A (possibly non-convex) simple polygon in the plane \(\mathbb{R}^2\).
EXAMPLES:
sage: from flatsurf import polygons, Polygon sage: s = polygons.square() sage: s Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)]) sage: Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)]) Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)])
- Element¶
alias of
EuclideanPolygonPoint
- change_ring(ring)[source]¶
Return a copy of this polygon whose vertices have coordinates over the base ring
ring
.EXAMPLES:
sage: from flatsurf import polygons sage: S = polygons.square() sage: K.<sqrt2> = NumberField(x^2 - 2, embedding=AA(2)**(1/2)) sage: S.change_ring(K) Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)]) sage: S.change_ring(K).base_ring() Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.4142...
- is_strictly_convex()[source]¶
Return whether this polygon is strictly convex.
EXAMPLES:
sage: from flatsurf import Polygon sage: Polygon(vertices=[(0,0), (1,0), (1,1)]).is_strictly_convex() doctest:warning ... UserWarning: is_strictly_convex() has been deprecated and will be removed in a future version of sage-flatsurf; use is_convex(strict=True) instead True sage: Polygon(vertices=[(0,0), (1,0), (2,0), (1,1)]).is_strictly_convex() False
- num_edges()[source]¶
Return the number of edges of this polygon.
EXAMPLES:
sage: from flatsurf import polygons sage: S = polygons.square() sage: S.num_edges() doctest:warning ... UserWarning: num_edges() has been deprecated and will be removed in a future version of sage-flatsurf; use len(vertices()) instead 4
- parent()[source]¶
Return the category this polygon belongs to.
EXAMPLES:
sage: from flatsurf import polygons sage: s = polygons.square() sage: s.parent() doctest:warning ... UserWarning: parent() of a polygon has been deprecated and will be removed in a future version of sage-flatsurf; use category() instead Category of convex simple euclidean rectangles over Rational Field
Note that the parent may change during the lifetime of a polygon as more of its features are discovered:
sage: from flatsurf import Polygon sage: p = Polygon(vertices=[(0, 0), (1, 0), (1, 1)]) sage: p.parent() Category of convex simple euclidean polygons over Rational Field sage: p.angles() (1/8, 1/4, 1/8) sage: p.parent() Category of convex simple euclidean triangles with angles (1/8, 1/4, 1/8) over Rational Field
- vertices(translation=None, marked_vertices=True)[source]¶
Return the vertices of this polygon in counterclockwise order as vectors in the real plane.
INPUT:
marked_vertices
– a boolean (default:True
); whether to include vertices with a π angle in the output.
EXAMPLES:
sage: from flatsurf import polygons sage: s = polygons.square() sage: s.vertices() ((0, 0), (1, 0), (1, 1), (0, 1))
- class flatsurf.geometry.polygon.EuclideanPolygonPoint(parent, xy)[source]¶
A point in a polygon.
EXAMPLES:
sage: from flatsurf import polygons sage: s = polygons.square() sage: s.an_element() (0, 0)
- position()[source]¶
Describe the position of this point in the polygon.
OUTPUT:
A
PolygonPosition
object.EXAMPLES:
sage: from flatsurf import polygons sage: s = polygons.square() sage: p = s.an_element() sage: p (0, 0) sage: p.position() point positioned on vertex 0 of polygon
See also
- flatsurf.geometry.polygon.EuclideanPolygonsWithAngles(*angles)[source]¶
Return the category of Euclidean polygons with prescribed
angles
over a (minimal) number field.This method is a convenience to interact with that category. To create polygons with prescribed angles over such a field, one should just use
Polygon()
directly, see below.INPUT:
angles
– a sequence of integers or rationals describing the angles of the polygon (the number get normalized so that they sum to (n-2)π automatically.
- flatsurf.geometry.polygon.Polygon(vertices, edges, angles, lengths, base_ring, category, check, *args, **kwds)[source]¶
Return a polygon from the given
vertices
,edges
, orangles
.INPUT:
vertices
– a sequence of vertices orNone
(default:None
); the vertices of the polygon as points in the real planeedges
– a sequence of vectors orNone
(default:None
); the vectors connecting the vertices of the polygonangles
– a sequence of numbers that prescribe the inner angles of the polygon orNone
(default:None
); the angles are rescaled so that their sum matches the sum of the angles in an ngon.lengths
– a sequence of numbers that prescribe the lengths of the edges of the polygon orNone
(default:None
)base_ring
– a ring orNone
(default:None
); the ring over which the polygon will be definedcategory
– a category orNone
(default:None
); the category the polygon will be in (further refined from the features of the polygon that are found during the construction.)check
– a boolean (default:True
); whether to check the consistency of the parameters or blindly trust them. Setting this toFalse
allows creation of degenerate polygons in some cases. While they might be somewhat functional, no guarantees are made about such polygons.
EXAMPLES:
A right triangle:
sage: from flatsurf import Polygon sage: Polygon(vertices=[(0, 0), (1, 0), (0, 1)]) Polygon(vertices=[(0, 0), (1, 0), (0, 1)])
A right triangle that is not based at the origin:
sage: Polygon(vertices=[(1, 0), (2, 0), (1, 1)]) Polygon(vertices=[(1, 0), (2, 0), (1, 1)])
A right triangle at the origin, specified by giving the edge vectors:
sage: Polygon(edges=[(1, 0), (-1, 1), (0, -1)]) Polygon(vertices=[(0, 0), (1, 0), (0, 1)])
When redundant information is given, it is checked for consistency:
sage: Polygon(vertices=[(0, 0), (1, 0), (0, 1)], edges=[(1, 0), (-1, 1), (0, -1)]) Polygon(vertices=[(0, 0), (1, 0), (0, 1)]) sage: Polygon(vertices=[(1, 0), (2, 0), (1, 1)], edges=[(1, 0), (-1, 1), (0, -1)]) Polygon(vertices=[(1, 0), (2, 0), (1, 1)]) sage: Polygon(vertices=[(0, 0), (2, 0), (1, 1)], edges=[(1, 0), (-1, 1), (0, -1)]) Traceback (most recent call last): ... ValueError: vertices and edges are not compatible
Polygons given by edges must be closed (in particular we do not add an edge automatically to close things up since this is often not what the user wanted):
sage: Polygon(edges=[(1, 0), (0, 1), (1, 1)]) Traceback (most recent call last): ... ValueError: polygon not closed
A polygon with prescribed angles:
sage: Polygon(angles=[2, 1, 1]) Polygon(vertices=[(0, 0), (1, 0), (0, 1)])
Again, if vertices and edges are also specified, they must be compatible with the angles:
sage: Polygon(angles=[2, 1, 1], vertices=[(0, 0), (1, 0), (0, 1)], edges=[(1, 0), (-1, 1), (0, -1)]) Polygon(vertices=[(0, 0), (1, 0), (0, 1)]) sage: Polygon(angles=[1, 2, 3], vertices=[(0, 0), (1, 0), (0, 1)], edges=[(1, 0), (-1, 1), (0, -1)]) Traceback (most recent call last): ... ValueError: polygon does not have the prescribed angles
When angles are specified, side lengths can also be prescribed:
sage: Polygon(angles=[1, 1, 1], lengths=[1, 1, 1]) Polygon(vertices=[(0, 0), (1, 0), (1/2, 1/2*c)])
The function will deduce lengths if one or two are missing:
sage: Polygon(angles=[1, 1, 1, 1], lengths=[1, 1, 1]) Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)]) sage: Polygon(angles=[1, 1, 1, 1], lengths=[1, 1]) Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)]) sage: Polygon(angles=[1, 1, 1, 1], lengths=[1]) Traceback (most recent call last): ... NotImplementedError: cannot construct a quadrilateral from 4 angles and 2 vertices
Equally, we deduce vertices or edges:
sage: Polygon(angles=[1, 1, 1, 1], vertices=[(0, 0), (1, 0), (1, 1)]) Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)]) sage: Polygon(angles=[1, 1, 1, 1], edges=[(1, 0), (0, 1)]) Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)])
When the angles are incompatible with the data, an error is reported (that might be somewhat cryptic at times):
sage: Polygon(angles=[1, 1, 1, 1], edges=[(1, 0), (0, 1), (1, 2)]) Traceback (most recent call last): ... NotImplementedError: cannot recover a rational angle from these numerical results
When lengths are given in addition to vertices or edges, they are checked for consistency:
sage: Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)], lengths=[1, 1, 1, 1]) Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)]) sage: Polygon(vertices=[(0, 0), (1, 0), (0, 1)], lengths=[1, 1, 1]) Traceback (most recent call last): ... ValueError: polygon does not have the prescribed lengths
Currently, we cannot create a polygon from just lengths:
sage: Polygon(lengths=[1, 1, 1]) Traceback (most recent call last): ... NotImplementedError: one of vertices, edges, or angles must be set
Polygons do not have to be convex:
sage: p = Polygon(vertices=[(0, 0), (1, 1), (2, 0), (2, 4), (0, 4)]) sage: p.describe_polygon() ('a', 'non-convex pentagon', 'non-convex pentagons')
Polygons must be positively oriented:
sage: Polygon(vertices=[(0, 0), (0, 1), (1, 0)]) Traceback (most recent call last): ... ValueError: polygon has negative area; probably the vertices are not in counter-clockwise order
Polygons must have at least three sides:
sage: Polygon(vertices=[(0, 0), (1, 0)]) Traceback (most recent call last): ... ValueError: polygon must have at least three sides sage: Polygon(vertices=[(0, 0), (1, 0), (2, 0)]) Traceback (most recent call last): ... ValueError: polygon has zero area
Currently, polygons must not self-intersect:
sage: p = Polygon(vertices=[(0, 0), (2, 0), (0, 1), (1, -1), (2, 1)]) Traceback (most recent call last): ... NotImplementedError: polygon self-intersects
Currently, all angles must be less than 2π:
sage: p = Polygon(angles=[14, 1, 1, 1, 1]) Traceback (most recent call last): ... NotImplementedError: each angle must be in (0, 2π)
- class flatsurf.geometry.polygon.PolygonPosition(position_type, edge=None, vertex=None)[source]¶
Describes the position of a point within or outside of a polygon.
- EDGE_INTERIOR = 2¶
- INTERIOR = 1¶
- OUTSIDE = 0¶
- VERTEX = 3¶
- class flatsurf.geometry.polygon.PolygonsConstructor[source]¶
- rectangle(width, height, **kwds)[source]¶
EXAMPLES:
sage: from flatsurf.geometry.polygon import polygons sage: polygons.rectangle(1,2) Polygon(vertices=[(0, 0), (1, 0), (1, 2), (0, 2)]) sage: K.<sqrt2> = QuadraticField(2) sage: polygons.rectangle(1,sqrt2) Polygon(vertices=[(0, 0), (1, 0), (1, sqrt2), (0, sqrt2)]) sage: _.category() Category of convex simple euclidean rectangles over Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095?
- static regular_ngon(n, field=None)[source]¶
Return a regular n-gon with unit length edges, first edge horizontal, and other vertices lying above this edge.
Assuming field is None (by default) the polygon is defined over a NumberField (the minimal number field determined by n). Otherwise you can set field equal to AA to define the polygon over the Algebraic Reals. Other values for the field parameter will result in a ValueError.
EXAMPLES:
sage: from flatsurf.geometry.polygon import polygons sage: p = polygons.regular_ngon(17) sage: p Polygon(vertices=[(0, 0), (1, 0), ..., (-1/2*a^14 + 15/2*a^12 - 45*a^10 + 275/2*a^8 - 225*a^6 + 189*a^4 - 70*a^2 + 15/2, 1/2*a)]) sage: polygons.regular_ngon(3,field=AA) Polygon(vertices=[(0, 0), (1, 0), (1/2, 0.866025403784439?)])
- static right_triangle(angle, leg0=None, leg1=None, hypotenuse=None)[source]¶
Return a right triangle in a number field with an angle of pi*angle.
You can specify the length of the first leg (
leg0
), the second leg (leg1
), or thehypotenuse
.EXAMPLES:
sage: from flatsurf import polygons sage: P = polygons.right_triangle(1/3, 1) sage: P Polygon(vertices=[(0, 0), (1, 0), (1, a)]) sage: P.base_ring() Number Field in a with defining polynomial y^2 - 3 with a = 1.732050807568878? sage: polygons.right_triangle(1/4,1) Polygon(vertices=[(0, 0), (1, 0), (1, 1)]) sage: polygons.right_triangle(1/4,1).base_ring() Rational Field
- square(side=1, **kwds)[source]¶
EXAMPLES:
sage: from flatsurf.geometry.polygon import polygons sage: polygons.square() Polygon(vertices=[(0, 0), (1, 0), (1, 1), (0, 1)]) sage: polygons.square(base_ring=QQbar).category() Category of convex simple euclidean rectangles over Algebraic Field
- triangle(a, b, c)[source]¶
Return the triangle with angles a*pi/N,b*pi/N,c*pi/N where N=a+b+c.
INPUT:
a
,b
,c
– integers
EXAMPLES:
sage: from flatsurf.geometry.polygon import polygons sage: T = polygons.triangle(3,4,5) sage: T Polygon(vertices=[(0, 0), (1, 0), (-1/2*c0 + 3/2, -1/2*c0 + 3/2)]) sage: T.base_ring() Number Field in c0 with defining polynomial x^2 - 3 with c0 = 1.732050807568878? sage: polygons.triangle(1,2,3).angles() (1/12, 1/6, 1/4)
Some fairly complicated examples:
sage: polygons.triangle(1, 15, 21) # long time (2s) Polygon(vertices=[(0, 0), (1, 0), (1/2*c^34 - 17*c^32 + 264*c^30 - 2480*c^28 + 15732*c^26 - 142481/2*c^24 + 237372*c^22 - 1182269/2*c^20 + 1106380*c^18 - 1552100*c^16 + 3229985/2*c^14 - 2445665/2*c^12 + 654017*c^10 - 472615/2*c^8 + 107809/2*c^6 - 13923/2*c^4 + 416*c^2 - 6, -1/2*c^27 + 27/2*c^25 - 323/2*c^23 + 1127*c^21 - 10165/2*c^19 + 31009/2*c^17 - 65093/2*c^15 + 46911*c^13 - 91091/2*c^11 + 57355/2*c^9 - 10994*c^7 + 4621/2*c^5 - 439/2*c^3 + 6*c)]) sage: polygons.triangle(2, 13, 26) # long time (3s) Polygon(vertices=[(0, 0), (1, 0), (1/2*c^30 - 15*c^28 + 405/2*c^26 - 1625*c^24 + 8625*c^22 - 31878*c^20 + 168245/2*c^18 - 159885*c^16 + 218025*c^14 - 209950*c^12 + 138567*c^10 - 59670*c^8 + 15470*c^6 - 2100*c^4 + 225/2*c^2 - 1/2, -1/2*c^39 + 19*c^37 - 333*c^35 + 3571*c^33 - 26212*c^31 + 139593*c^29 - 557844*c^27 + 1706678*c^25 - 8085237/2*c^23 + 7449332*c^21 - 10671265*c^19 + 11812681*c^17 - 9983946*c^15 + 6317339*c^13 - 5805345/2*c^11 + 1848183/2*c^9 - 378929/2*c^7 + 44543/2*c^5 - 2487/2*c^3 + 43/2*c)])