Functions for plotting polyhedra¶
- class sage.geometry.polyhedron.plot.Projection(polyhedron, proj=<function projection_func_identity>)[source]¶
Bases:
SageObjectThe projection of a
Polyhedron.This class keeps track of the necessary data to plot the input polyhedron.
- coord_index_of(v)[source]¶
Convert a coordinate vector to its internal index.
EXAMPLES:
sage: p = polytopes.hypercube(3) sage: proj = p.projection() sage: proj.coord_index_of(vector((1,1,1))) 2
>>> from sage.all import * >>> p = polytopes.hypercube(Integer(3)) >>> proj = p.projection() >>> proj.coord_index_of(vector((Integer(1),Integer(1),Integer(1)))) 2
p = polytopes.hypercube(3) proj = p.projection() proj.coord_index_of(vector((1,1,1)))
- coord_indices_of(v_list)[source]¶
Convert list of coordinate vectors to the corresponding list of internal indices.
EXAMPLES:
sage: p = polytopes.hypercube(3) sage: proj = p.projection() sage: proj.coord_indices_of([vector((1,1,1)), vector((1,-1,1))]) [2, 3]
>>> from sage.all import * >>> p = polytopes.hypercube(Integer(3)) >>> proj = p.projection() >>> proj.coord_indices_of([vector((Integer(1),Integer(1),Integer(1))), vector((Integer(1),-Integer(1),Integer(1)))]) [2, 3]
p = polytopes.hypercube(3) proj = p.projection() proj.coord_indices_of([vector((1,1,1)), vector((1,-1,1))])
- coordinates_of(coord_index_list)[source]¶
Given a list of indices, return the projected coordinates.
EXAMPLES:
sage: p = polytopes.simplex(4, project=True).projection() sage: p.coordinates_of([1]) [[-0.7071067812, 0.4082482905, 0.2886751346, 0.2236067977]]
>>> from sage.all import * >>> p = polytopes.simplex(Integer(4), project=True).projection() >>> p.coordinates_of([Integer(1)]) [[-0.7071067812, 0.4082482905, 0.2886751346, 0.2236067977]]
p = polytopes.simplex(4, project=True).projection() p.coordinates_of([1])
- identity()[source]¶
Return the identity projection of the polyhedron.
EXAMPLES:
sage: p = polytopes.icosahedron(exact=False) sage: from sage.geometry.polyhedron.plot import Projection sage: pproj = Projection(p) sage: ppid = pproj.identity() sage: ppid.dimension 3
>>> from sage.all import * >>> p = polytopes.icosahedron(exact=False) >>> from sage.geometry.polyhedron.plot import Projection >>> pproj = Projection(p) >>> ppid = pproj.identity() >>> ppid.dimension 3
p = polytopes.icosahedron(exact=False) from sage.geometry.polyhedron.plot import Projection pproj = Projection(p) ppid = pproj.identity() ppid.dimension
- render_0d(point_opts=None, line_opts=None, polygon_opts=None)[source]¶
Return 0d rendering of the projection of a polyhedron into 2-dimensional ambient space.
INPUT:
See
plot().OUTPUT: a 2-d graphics object
EXAMPLES:
sage: print(Polyhedron([]).projection().render_0d().description()) sage: P = Polyhedron(ieqs=[(1,)]) sage: print(P.projection().render_0d().description()) Point set defined by 1 point(s): [(0.0, 0.0)]
>>> from sage.all import * >>> print(Polyhedron([]).projection().render_0d().description()) <BLANKLINE> >>> P = Polyhedron(ieqs=[(Integer(1),)]) >>> print(P.projection().render_0d().description()) Point set defined by 1 point(s): [(0.0, 0.0)]
print(Polyhedron([]).projection().render_0d().description()) P = Polyhedron(ieqs=[(1,)]) print(P.projection().render_0d().description())
- render_1d(point_opts=None, line_opts=None, polygon_opts=None)[source]¶
Return 1d rendering of the projection of a polyhedron into 2-dimensional ambient space.
INPUT:
See
plot().OUTPUT: a 2-d graphics object
EXAMPLES:
sage: Polyhedron([(0,), (1,)]).projection().render_1d() Graphics object consisting of 2 graphics primitives
>>> from sage.all import * >>> Polyhedron([(Integer(0),), (Integer(1),)]).projection().render_1d() Graphics object consisting of 2 graphics primitives
Polyhedron([(0,), (1,)]).projection().render_1d()
- render_2d(point_opts=None, line_opts=None, polygon_opts=None)[source]¶
Return 2d rendering of the projection of a polyhedron into 2-dimensional ambient space.
EXAMPLES:
sage: p1 = Polyhedron(vertices=[[1,1]], rays=[[1,1]]) sage: q1 = p1.projection() sage: p2 = Polyhedron(vertices=[[1,0], [0,1], [0,0]]) sage: q2 = p2.projection() sage: p3 = Polyhedron(vertices=[[1,2]]) sage: q3 = p3.projection() sage: p4 = Polyhedron(vertices=[[2,0]], rays=[[1,-1]], lines=[[1,1]]) sage: q4 = p4.projection() sage: q1.plot() + q2.plot() + q3.plot() + q4.plot() Graphics object consisting of 18 graphics primitives
>>> from sage.all import * >>> p1 = Polyhedron(vertices=[[Integer(1),Integer(1)]], rays=[[Integer(1),Integer(1)]]) >>> q1 = p1.projection() >>> p2 = Polyhedron(vertices=[[Integer(1),Integer(0)], [Integer(0),Integer(1)], [Integer(0),Integer(0)]]) >>> q2 = p2.projection() >>> p3 = Polyhedron(vertices=[[Integer(1),Integer(2)]]) >>> q3 = p3.projection() >>> p4 = Polyhedron(vertices=[[Integer(2),Integer(0)]], rays=[[Integer(1),-Integer(1)]], lines=[[Integer(1),Integer(1)]]) >>> q4 = p4.projection() >>> q1.plot() + q2.plot() + q3.plot() + q4.plot() Graphics object consisting of 18 graphics primitives
p1 = Polyhedron(vertices=[[1,1]], rays=[[1,1]]) q1 = p1.projection() p2 = Polyhedron(vertices=[[1,0], [0,1], [0,0]]) q2 = p2.projection() p3 = Polyhedron(vertices=[[1,2]]) q3 = p3.projection() p4 = Polyhedron(vertices=[[2,0]], rays=[[1,-1]], lines=[[1,1]]) q4 = p4.projection() q1.plot() + q2.plot() + q3.plot() + q4.plot()
- render_3d(point_opts=None, line_opts=None, polygon_opts=None)[source]¶
Return 3d rendering of a polyhedron projected into 3-dimensional ambient space.
EXAMPLES:
sage: p1 = Polyhedron(vertices=[[1,1,1]], rays=[[1,1,1]]) sage: p2 = Polyhedron(vertices=[[2,0,0], [0,2,0], [0,0,2]]) sage: p3 = Polyhedron(vertices=[[1,0,0], [0,1,0], [0,0,1]], ....: rays=[[-1,-1,-1]]) sage: (p1.projection().plot() + p2.projection().plot() ....: + p3.projection().plot()) Graphics3d Object
>>> from sage.all import * >>> p1 = Polyhedron(vertices=[[Integer(1),Integer(1),Integer(1)]], rays=[[Integer(1),Integer(1),Integer(1)]]) >>> p2 = Polyhedron(vertices=[[Integer(2),Integer(0),Integer(0)], [Integer(0),Integer(2),Integer(0)], [Integer(0),Integer(0),Integer(2)]]) >>> p3 = Polyhedron(vertices=[[Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),Integer(1)]], ... rays=[[-Integer(1),-Integer(1),-Integer(1)]]) >>> (p1.projection().plot() + p2.projection().plot() ... + p3.projection().plot()) Graphics3d Object
p1 = Polyhedron(vertices=[[1,1,1]], rays=[[1,1,1]]) p2 = Polyhedron(vertices=[[2,0,0], [0,2,0], [0,0,2]]) p3 = Polyhedron(vertices=[[1,0,0], [0,1,0], [0,0,1]], rays=[[-1,-1,-1]]) (p1.projection().plot() + p2.projection().plot() + p3.projection().plot())It correctly handles various degenerate cases:
sage: Polyhedron(lines=[[1,0,0], [0,1,0], [0,0,1]]).plot() # whole space Graphics3d Object sage: Polyhedron(vertices=[[1,1,1]], rays=[[1,0,0]], ....: lines=[[0,1,0], [0,0,1]]).plot() # half space Graphics3d Object sage: Polyhedron(lines=[[0,1,0], [0,0,1]], ....: vertices=[[1,1,1]]).plot() # R^2 in R^3 Graphics3d Object sage: Polyhedron(rays=[[0,1,0], [0,0,1]], # quadrant wedge in R^2 ....: lines=[[1,0,0]]).plot() Graphics3d Object sage: Polyhedron(rays=[[0,1,0]], # upper half plane in R^3 ....: lines=[[1,0,0]]).plot() Graphics3d Object sage: Polyhedron(lines=[[1,0,0]]).plot() # R^1 in R^2 Graphics3d Object sage: Polyhedron(rays=[[0,1,0]]).plot() # Half-line in R^3 Graphics3d Object sage: Polyhedron(vertices=[[1,1,1]]).plot() # point in R^3 Graphics3d Object
>>> from sage.all import * >>> Polyhedron(lines=[[Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),Integer(1)]]).plot() # whole space Graphics3d Object >>> Polyhedron(vertices=[[Integer(1),Integer(1),Integer(1)]], rays=[[Integer(1),Integer(0),Integer(0)]], ... lines=[[Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),Integer(1)]]).plot() # half space Graphics3d Object >>> Polyhedron(lines=[[Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),Integer(1)]], ... vertices=[[Integer(1),Integer(1),Integer(1)]]).plot() # R^2 in R^3 Graphics3d Object >>> Polyhedron(rays=[[Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),Integer(1)]], # quadrant wedge in R^2 ... lines=[[Integer(1),Integer(0),Integer(0)]]).plot() Graphics3d Object >>> Polyhedron(rays=[[Integer(0),Integer(1),Integer(0)]], # upper half plane in R^3 ... lines=[[Integer(1),Integer(0),Integer(0)]]).plot() Graphics3d Object >>> Polyhedron(lines=[[Integer(1),Integer(0),Integer(0)]]).plot() # R^1 in R^2 Graphics3d Object >>> Polyhedron(rays=[[Integer(0),Integer(1),Integer(0)]]).plot() # Half-line in R^3 Graphics3d Object >>> Polyhedron(vertices=[[Integer(1),Integer(1),Integer(1)]]).plot() # point in R^3 Graphics3d Object
Polyhedron(lines=[[1,0,0], [0,1,0], [0,0,1]]).plot() # whole space Polyhedron(vertices=[[1,1,1]], rays=[[1,0,0]], lines=[[0,1,0], [0,0,1]]).plot() # half space Polyhedron(lines=[[0,1,0], [0,0,1]], vertices=[[1,1,1]]).plot() # R^2 in R^3 Polyhedron(rays=[[0,1,0], [0,0,1]], # quadrant wedge in R^2 lines=[[1,0,0]]).plot() Polyhedron(rays=[[0,1,0]], # upper half plane in R^3 lines=[[1,0,0]]).plot() Polyhedron(lines=[[1,0,0]]).plot() # R^1 in R^2 Polyhedron(rays=[[0,1,0]]).plot() # Half-line in R^3 Polyhedron(vertices=[[1,1,1]]).plot() # point in R^3The origin is not included, if it is not in the polyhedron (Issue #23555):
sage: Q = Polyhedron([[100],[101]]) sage: P = Q*Q*Q; P A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices sage: p = P.plot() sage: p.bounding_box() ((100.0, 100.0, 100.0), (101.0, 101.0, 101.0))
>>> from sage.all import * >>> Q = Polyhedron([[Integer(100)],[Integer(101)]]) >>> P = Q*Q*Q; P A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices >>> p = P.plot() >>> p.bounding_box() ((100.0, 100.0, 100.0), (101.0, 101.0, 101.0))
Q = Polyhedron([[100],[101]]) P = Q*Q*Q; P p = P.plot() p.bounding_box()
Plot 3d polytope with rainbow colors:
sage: polytopes.hypercube(3).plot(polygon='rainbow', alpha=0.4) Graphics3d Object
>>> from sage.all import * >>> polytopes.hypercube(Integer(3)).plot(polygon='rainbow', alpha=RealNumber('0.4')) Graphics3d Object
polytopes.hypercube(3).plot(polygon='rainbow', alpha=0.4)
- render_fill_2d(**kwds)[source]¶
Return the filled interior (a polygon) of a polyhedron in 2d.
EXAMPLES:
sage: cps = [i^3 for i in srange(-2, 2, 1/5)] sage: p = Polyhedron(vertices=[[(t^2-1)/(t^2+1), 2*t/(t^2+1)] for t in cps]) sage: proj = p.projection() sage: filled_poly = proj.render_fill_2d() sage: filled_poly.axes_width() 0.8
>>> from sage.all import * >>> cps = [i**Integer(3) for i in srange(-Integer(2), Integer(2), Integer(1)/Integer(5))] >>> p = Polyhedron(vertices=[[(t**Integer(2)-Integer(1))/(t**Integer(2)+Integer(1)), Integer(2)*t/(t**Integer(2)+Integer(1))] for t in cps]) >>> proj = p.projection() >>> filled_poly = proj.render_fill_2d() >>> filled_poly.axes_width() 0.8
cps = [i^3 for i in srange(-2, 2, 1/5)] p = Polyhedron(vertices=[[(t^2-1)/(t^2+1), 2*t/(t^2+1)] for t in cps]) proj = p.projection() filled_poly = proj.render_fill_2d() filled_poly.axes_width()
- render_line_1d(**kwds)[source]¶
Return the line of a polyhedron in 1d.
INPUT:
**kwds– options passed through toline2d()
OUTPUT: a 2-d graphics object
EXAMPLES:
sage: outline = polytopes.hypercube(1).projection().render_line_1d() sage: outline._objects[0] Line defined by 2 points
>>> from sage.all import * >>> outline = polytopes.hypercube(Integer(1)).projection().render_line_1d() >>> outline._objects[Integer(0)] Line defined by 2 points
outline = polytopes.hypercube(1).projection().render_line_1d() outline._objects[0]
- render_outline_2d(**kwds)[source]¶
Return the outline (edges) of a polyhedron in 2d.
EXAMPLES:
sage: penta = polytopes.regular_polygon(5) sage: outline = penta.projection().render_outline_2d() sage: outline._objects[0] Line defined by 2 points
>>> from sage.all import * >>> penta = polytopes.regular_polygon(Integer(5)) >>> outline = penta.projection().render_outline_2d() >>> outline._objects[Integer(0)] Line defined by 2 points
penta = polytopes.regular_polygon(5) outline = penta.projection().render_outline_2d() outline._objects[0]
- render_points_1d(**kwds)[source]¶
Return the points of a polyhedron in 1d.
INPUT:
**kwds– options passed through topoint2d()
OUTPUT: a 2-d graphics object
EXAMPLES:
sage: cube1 = polytopes.hypercube(1) sage: proj = cube1.projection() sage: points = proj.render_points_1d() sage: points._objects [Point set defined by 2 point(s)]
>>> from sage.all import * >>> cube1 = polytopes.hypercube(Integer(1)) >>> proj = cube1.projection() >>> points = proj.render_points_1d() >>> points._objects [Point set defined by 2 point(s)]
cube1 = polytopes.hypercube(1) proj = cube1.projection() points = proj.render_points_1d() points._objects
- render_points_2d(**kwds)[source]¶
Return the points of a polyhedron in 2d.
EXAMPLES:
sage: hex = polytopes.regular_polygon(6) sage: proj = hex.projection() sage: hex_points = proj.render_points_2d() sage: hex_points._objects [Point set defined by 6 point(s)]
>>> from sage.all import * >>> hex = polytopes.regular_polygon(Integer(6)) >>> proj = hex.projection() >>> hex_points = proj.render_points_2d() >>> hex_points._objects [Point set defined by 6 point(s)]
hex = polytopes.regular_polygon(6) proj = hex.projection() hex_points = proj.render_points_2d() hex_points._objects
- render_solid_3d(**kwds)[source]¶
Return solid 3d rendering of a 3d polytope.
EXAMPLES:
sage: p = polytopes.hypercube(3).projection() sage: p_solid = p.render_solid_3d(opacity=.7) sage: type(p_solid) <class 'sage.plot.plot3d.index_face_set.IndexFaceSet'>
>>> from sage.all import * >>> p = polytopes.hypercube(Integer(3)).projection() >>> p_solid = p.render_solid_3d(opacity=RealNumber('.7')) >>> type(p_solid) <class 'sage.plot.plot3d.index_face_set.IndexFaceSet'>
p = polytopes.hypercube(3).projection() p_solid = p.render_solid_3d(opacity=.7) type(p_solid)
- render_vertices_3d(**kwds)[source]¶
Return the 3d rendering of the vertices.
EXAMPLES:
sage: p = polytopes.cross_polytope(3) sage: proj = p.projection() sage: verts = proj.render_vertices_3d() sage: verts.bounding_box() ((-1.0, -1.0, -1.0), (1.0, 1.0, 1.0))
>>> from sage.all import * >>> p = polytopes.cross_polytope(Integer(3)) >>> proj = p.projection() >>> verts = proj.render_vertices_3d() >>> verts.bounding_box() ((-1.0, -1.0, -1.0), (1.0, 1.0, 1.0))
p = polytopes.cross_polytope(3) proj = p.projection() verts = proj.render_vertices_3d() verts.bounding_box()
- render_wireframe_3d(**kwds)[source]¶
Return the 3d wireframe rendering.
EXAMPLES:
sage: cube = polytopes.hypercube(3) sage: cube_proj = cube.projection() sage: wire = cube_proj.render_wireframe_3d() sage: print(wire.tachyon().split('\n')[77]) # for testing FCylinder base 1.0 1.0 -1.0 apex -1.0 1.0 -1.0 rad 0.005 texture...
>>> from sage.all import * >>> cube = polytopes.hypercube(Integer(3)) >>> cube_proj = cube.projection() >>> wire = cube_proj.render_wireframe_3d() >>> print(wire.tachyon().split('\n')[Integer(77)]) # for testing FCylinder base 1.0 1.0 -1.0 apex -1.0 1.0 -1.0 rad 0.005 texture...
cube = polytopes.hypercube(3) cube_proj = cube.projection() wire = cube_proj.render_wireframe_3d() print(wire.tachyon().split('\n')[77]) # for testing
- schlegel(facet=None, position=None)[source]¶
Return the Schlegel projection.
The facet is orthonormally transformed into its affine hull.
The position specifies a point coming out of the barycenter of the facet from which the other vertices will be projected into the facet.
INPUT:
facet– a PolyhedronFace; the facet into which the Schlegel diagram is created. The default is the first facet.position– a positive number. Determines a relative distance from the barycenter offacet. A value close to 0 will place the projection point close to the facet and a large value further away. If the given value is too large, an error is returned. If no position is given, it takes the midpoint of the possible point of views along a line spanned by the barycenter of the facet and a valid point outside the facet.
EXAMPLES:
sage: cube4 = polytopes.hypercube(4) sage: from sage.geometry.polyhedron.plot import Projection sage: Projection(cube4).schlegel() The projection of a polyhedron into 3 dimensions sage: _.plot() Graphics3d Object
>>> from sage.all import * >>> cube4 = polytopes.hypercube(Integer(4)) >>> from sage.geometry.polyhedron.plot import Projection >>> Projection(cube4).schlegel() The projection of a polyhedron into 3 dimensions >>> _.plot() Graphics3d Object
cube4 = polytopes.hypercube(4) from sage.geometry.polyhedron.plot import Projection Projection(cube4).schlegel() _.plot()
The 4-cube with a truncated vertex seen into the resulting tetrahedron facet:
sage: tcube4 = cube4.face_truncation(cube4.faces(0)[0]) sage: tcube4.facets()[4] A 3-dimensional face of a Polyhedron in QQ^4 defined as the convex hull of 4 vertices sage: into_tetra = Projection(tcube4).schlegel(tcube4.facets()[4]) sage: into_tetra.plot() Graphics3d Object
>>> from sage.all import * >>> tcube4 = cube4.face_truncation(cube4.faces(Integer(0))[Integer(0)]) >>> tcube4.facets()[Integer(4)] A 3-dimensional face of a Polyhedron in QQ^4 defined as the convex hull of 4 vertices >>> into_tetra = Projection(tcube4).schlegel(tcube4.facets()[Integer(4)]) >>> into_tetra.plot() Graphics3d Object
tcube4 = cube4.face_truncation(cube4.faces(0)[0]) tcube4.facets()[4] into_tetra = Projection(tcube4).schlegel(tcube4.facets()[4]) into_tetra.plot()
Taking a larger value for the position changes the image:
sage: into_tetra_far = Projection(tcube4).schlegel(tcube4.facets()[4], 4) sage: into_tetra_far.plot() Graphics3d Object
>>> from sage.all import * >>> into_tetra_far = Projection(tcube4).schlegel(tcube4.facets()[Integer(4)], Integer(4)) >>> into_tetra_far.plot() Graphics3d Object
into_tetra_far = Projection(tcube4).schlegel(tcube4.facets()[4], 4) into_tetra_far.plot()
A value which is too large or negative give a projection point that sees more than one facet resulting in a error:
sage: Projection(tcube4).schlegel(tcube4.facets()[4], 5) Traceback (most recent call last): ... ValueError: the chosen position is too large sage: Projection(tcube4).schlegel(tcube4.facets()[4], -1) Traceback (most recent call last): ... ValueError: 'position' should be a positive number
>>> from sage.all import * >>> Projection(tcube4).schlegel(tcube4.facets()[Integer(4)], Integer(5)) Traceback (most recent call last): ... ValueError: the chosen position is too large >>> Projection(tcube4).schlegel(tcube4.facets()[Integer(4)], -Integer(1)) Traceback (most recent call last): ... ValueError: 'position' should be a positive number
Projection(tcube4).schlegel(tcube4.facets()[4], 5) Projection(tcube4).schlegel(tcube4.facets()[4], -1)
- stereographic(projection_point=None)[source]¶
Return the stereographic projection.
INPUT:
projection_point– the projection point. This must be distinct from the polyhedron’s vertices. Default is \((1,0,\dots,0)\).
EXAMPLES:
sage: from sage.geometry.polyhedron.plot import Projection sage: proj = Projection(polytopes.buckyball()); proj # long time The projection of a polyhedron into 3 dimensions sage: proj.stereographic([5,2,3]).plot() # long time Graphics object consisting of 123 graphics primitives sage: Projection(polytopes.twenty_four_cell()).stereographic([2,0,0,0]) The projection of a polyhedron into 3 dimensions
>>> from sage.all import * >>> from sage.geometry.polyhedron.plot import Projection >>> proj = Projection(polytopes.buckyball()); proj # long time The projection of a polyhedron into 3 dimensions >>> proj.stereographic([Integer(5),Integer(2),Integer(3)]).plot() # long time Graphics object consisting of 123 graphics primitives >>> Projection(polytopes.twenty_four_cell()).stereographic([Integer(2),Integer(0),Integer(0),Integer(0)]) The projection of a polyhedron into 3 dimensions
from sage.geometry.polyhedron.plot import Projection proj = Projection(polytopes.buckyball()); proj # long time proj.stereographic([5,2,3]).plot() # long time Projection(polytopes.twenty_four_cell()).stereographic([2,0,0,0])
- tikz(view=[0, 0, 1], angle=0, scale=1, edge_color='blue!95!black', facet_color='blue!95!black', opacity=0.8, vertex_color='green', axis=False, output_type='TikzPicture')[source]¶
Return a tikz picture of
selfas a string or as aTikzPictureaccording to a projectionviewand an angleangleobtained via the threejs viewer.INPUT:
view– list (default: [0,0,1]) representing the rotation axis (see note below)angle– integer (default: 0); angle of rotation in degree from 0 to 360 (see note below)scale– integer (default: 1); the scaling of the tikz pictureedge_color– string (default:'blue!95!black'); representing colors which tikz recognizesfacet_color– string (default:'blue!95!black'); representing colors which tikz recognizesvertex_color– string (default:'green'); representing colors which tikz recognizesopacity– real number (default: 0.8) between 0 and 1 giving the opacity of the front facetsaxis– boolean (default:False); draw the axes at the origin or notoutput_type– string (default:'TikzPicture'); valid values are'LatexExpr'and'TikzPicture', whether to return aLatexExprobject (which inherits from Pythonstr) or aTikzPictureobject from modulesage.misc.latex_standalone
OUTPUT:
LatexExprobject orTikzPictureobjectNote
The inputs
viewandanglecan be obtained by visualizing it using.show(aspect_ratio=1). This will open an interactive view in your default browser, where you can rotate the polytope. Once the desired view angle is found, click on the information icon in the lower right-hand corner and select Get Viewpoint. This will copy a string of the form ‘[x,y,z],angle’ to your local clipboard. Go back to Sage and typeImg = P.projection().tikz([x,y,z],angle).The inputs
viewandanglecan also be obtained from the viewer Jmol:1) Right click on the image 2) Select ``Console`` 3) Select the tab ``State`` 4) Scroll to the line ``moveto``
It reads something like:
moveto 0.0 {x y z angle} ScaleThe
viewis then [x,y,z] andangleis angle. The following number is the scale.Jmol performs a rotation of
angledegrees along the vector [x,y,z] and show the result from the z-axis.EXAMPLES:
sage: P1 = polytopes.small_rhombicuboctahedron() sage: Image1 = P1.projection().tikz([1,3,5], 175, scale=4, ....: output_type='TikzPicture') sage: type(Image1) <class 'sage.misc.latex_standalone.TikzPicture'> sage: Image1 \documentclass[tikz]{standalone} \begin{document} \begin{tikzpicture}% [x={(-0.939161cm, 0.244762cm)}, y={(0.097442cm, -0.482887cm)}, z={(0.329367cm, 0.840780cm)}, scale=4.000000, ... Use print to see the full content. ... \node[vertex] at (-2.41421, 1.00000, -1.00000) {}; \node[vertex] at (-2.41421, -1.00000, 1.00000) {}; %% %% \end{tikzpicture} \end{document} sage: _ = Image1.tex('polytope-tikz1.tex') # not tested sage: _ = Image1.png('polytope-tikz1.png') # not tested sage: _ = Image1.pdf('polytope-tikz1.pdf') # not tested sage: _ = Image1.svg('polytope-tikz1.svg') # not tested
>>> from sage.all import * >>> P1 = polytopes.small_rhombicuboctahedron() >>> Image1 = P1.projection().tikz([Integer(1),Integer(3),Integer(5)], Integer(175), scale=Integer(4), ... output_type='TikzPicture') >>> type(Image1) <class 'sage.misc.latex_standalone.TikzPicture'> >>> Image1 \documentclass[tikz]{standalone} \begin{document} \begin{tikzpicture}% [x={(-0.939161cm, 0.244762cm)}, y={(0.097442cm, -0.482887cm)}, z={(0.329367cm, 0.840780cm)}, scale=4.000000, ... Use print to see the full content. ... \node[vertex] at (-2.41421, 1.00000, -1.00000) {}; \node[vertex] at (-2.41421, -1.00000, 1.00000) {}; %% %% \end{tikzpicture} \end{document} >>> _ = Image1.tex('polytope-tikz1.tex') # not tested >>> _ = Image1.png('polytope-tikz1.png') # not tested >>> _ = Image1.pdf('polytope-tikz1.pdf') # not tested >>> _ = Image1.svg('polytope-tikz1.svg') # not tested
P1 = polytopes.small_rhombicuboctahedron() Image1 = P1.projection().tikz([1,3,5], 175, scale=4, output_type='TikzPicture') type(Image1) Image1 _ = Image1.tex('polytope-tikz1.tex') # not tested _ = Image1.png('polytope-tikz1.png') # not tested _ = Image1.pdf('polytope-tikz1.pdf') # not tested _ = Image1.svg('polytope-tikz1.svg') # not testedA second example:
sage: P2 = Polyhedron(vertices=[[1, 1], [1, 2], [2, 1]]) sage: Image2 = P2.projection().tikz(scale=3, edge_color='blue!95!black', ....: facet_color='orange!95!black', opacity=0.4, ....: vertex_color='yellow', axis=True, ....: output_type='TikzPicture') sage: Image2 \documentclass[tikz]{standalone} \begin{document} \begin{tikzpicture}% [scale=3.000000, back/.style={loosely dotted, thin}, edge/.style={color=blue!95!black, thick}, facet/.style={fill=orange!95!black,fill opacity=0.400000}, ... Use print to see the full content. ... \node[vertex] at (1.00000, 2.00000) {}; \node[vertex] at (2.00000, 1.00000) {}; %% %% \end{tikzpicture} \end{document}
>>> from sage.all import * >>> P2 = Polyhedron(vertices=[[Integer(1), Integer(1)], [Integer(1), Integer(2)], [Integer(2), Integer(1)]]) >>> Image2 = P2.projection().tikz(scale=Integer(3), edge_color='blue!95!black', ... facet_color='orange!95!black', opacity=RealNumber('0.4'), ... vertex_color='yellow', axis=True, ... output_type='TikzPicture') >>> Image2 \documentclass[tikz]{standalone} \begin{document} \begin{tikzpicture}% [scale=3.000000, back/.style={loosely dotted, thin}, edge/.style={color=blue!95!black, thick}, facet/.style={fill=orange!95!black,fill opacity=0.400000}, ... Use print to see the full content. ... \node[vertex] at (1.00000, 2.00000) {}; \node[vertex] at (2.00000, 1.00000) {}; %% %% \end{tikzpicture} \end{document}
P2 = Polyhedron(vertices=[[1, 1], [1, 2], [2, 1]]) Image2 = P2.projection().tikz(scale=3, edge_color='blue!95!black', facet_color='orange!95!black', opacity=0.4, vertex_color='yellow', axis=True, output_type='TikzPicture') Image2The second example using a LatexExpr as output type:
sage: Image2 = P2.projection().tikz(scale=3, edge_color='blue!95!black', ....: facet_color='orange!95!black', opacity=0.4, ....: vertex_color='yellow', axis=True, ....: output_type='LatexExpr') sage: type(Image2) <class 'sage.misc.latex.LatexExpr'> sage: print('\n'.join(Image2.splitlines()[:4])) \begin{tikzpicture}% [scale=3.000000, back/.style={loosely dotted, thin}, edge/.style={color=blue!95!black, thick}, sage: with open('polytope-tikz2.tex', 'w') as f: # not tested ....: _ = f.write(Image2)
>>> from sage.all import * >>> Image2 = P2.projection().tikz(scale=Integer(3), edge_color='blue!95!black', ... facet_color='orange!95!black', opacity=RealNumber('0.4'), ... vertex_color='yellow', axis=True, ... output_type='LatexExpr') >>> type(Image2) <class 'sage.misc.latex.LatexExpr'> >>> print('\n'.join(Image2.splitlines()[:Integer(4)])) \begin{tikzpicture}% [scale=3.000000, back/.style={loosely dotted, thin}, edge/.style={color=blue!95!black, thick}, >>> with open('polytope-tikz2.tex', 'w') as f: # not tested ... _ = f.write(Image2)
Image2 = P2.projection().tikz(scale=3, edge_color='blue!95!black', facet_color='orange!95!black', opacity=0.4, vertex_color='yellow', axis=True, output_type='LatexExpr') type(Image2) print('\n'.join(Image2.splitlines()[:4])) with open('polytope-tikz2.tex', 'w') as f: # not tested _ = f.write(Image2)A third example:
sage: P3 = Polyhedron(vertices=[[-1, -1, 2], [-1, 2, -1], [2, -1, -1]]); P3 A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 3 vertices sage: Image3 = P3.projection().tikz([0.5, -1, -0.1], 55, scale=3, ....: edge_color='blue!95!black', ....: facet_color='orange!95!black', opacity=0.7, ....: vertex_color='yellow', axis=True) sage: Image3 \documentclass[tikz]{standalone} \begin{document} \begin{tikzpicture}% [x={(0.658184cm, -0.242192cm)}, y={(-0.096240cm, 0.912008cm)}, z={(-0.746680cm, -0.331036cm)}, scale=3.000000, ... Use print to see the full content. ... \node[vertex] at (-1.00000, 2.00000, -1.00000) {}; \node[vertex] at (2.00000, -1.00000, -1.00000) {}; %% %% \end{tikzpicture} \end{document} sage: _ = Image3.tex('polytope-tikz3.tex') # not tested sage: _ = Image3.png('polytope-tikz3.png') # not tested sage: _ = Image3.pdf('polytope-tikz3.pdf') # not tested sage: _ = Image3.svg('polytope-tikz3.svg') # not tested
>>> from sage.all import * >>> P3 = Polyhedron(vertices=[[-Integer(1), -Integer(1), Integer(2)], [-Integer(1), Integer(2), -Integer(1)], [Integer(2), -Integer(1), -Integer(1)]]); P3 A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 3 vertices >>> Image3 = P3.projection().tikz([RealNumber('0.5'), -Integer(1), -RealNumber('0.1')], Integer(55), scale=Integer(3), ... edge_color='blue!95!black', ... facet_color='orange!95!black', opacity=RealNumber('0.7'), ... vertex_color='yellow', axis=True) >>> Image3 \documentclass[tikz]{standalone} \begin{document} \begin{tikzpicture}% [x={(0.658184cm, -0.242192cm)}, y={(-0.096240cm, 0.912008cm)}, z={(-0.746680cm, -0.331036cm)}, scale=3.000000, ... Use print to see the full content. ... \node[vertex] at (-1.00000, 2.00000, -1.00000) {}; \node[vertex] at (2.00000, -1.00000, -1.00000) {}; %% %% \end{tikzpicture} \end{document} >>> _ = Image3.tex('polytope-tikz3.tex') # not tested >>> _ = Image3.png('polytope-tikz3.png') # not tested >>> _ = Image3.pdf('polytope-tikz3.pdf') # not tested >>> _ = Image3.svg('polytope-tikz3.svg') # not tested
P3 = Polyhedron(vertices=[[-1, -1, 2], [-1, 2, -1], [2, -1, -1]]); P3 Image3 = P3.projection().tikz([0.5, -1, -0.1], 55, scale=3, edge_color='blue!95!black', facet_color='orange!95!black', opacity=0.7, vertex_color='yellow', axis=True) Image3 _ = Image3.tex('polytope-tikz3.tex') # not tested _ = Image3.png('polytope-tikz3.png') # not tested _ = Image3.pdf('polytope-tikz3.pdf') # not tested _ = Image3.svg('polytope-tikz3.svg') # not testedA fourth example:
sage: P = Polyhedron(vertices=[[1,1,0,0], [1,2,0,0], ....: [2,1,0,0], [0,0,1,0], [0,0,0,1]]); P A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices sage: P.projection().tikz(output_type='TikzPicture') Traceback (most recent call last): ... NotImplementedError: The polytope has to live in 2 or 3 dimensions.
>>> from sage.all import * >>> P = Polyhedron(vertices=[[Integer(1),Integer(1),Integer(0),Integer(0)], [Integer(1),Integer(2),Integer(0),Integer(0)], ... [Integer(2),Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),Integer(0),Integer(1)]]); P A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices >>> P.projection().tikz(output_type='TikzPicture') Traceback (most recent call last): ... NotImplementedError: The polytope has to live in 2 or 3 dimensions.
P = Polyhedron(vertices=[[1,1,0,0], [1,2,0,0], [2,1,0,0], [0,0,1,0], [0,0,0,1]]); P P.projection().tikz(output_type='TikzPicture')Todo
Make it possible to draw Schlegel diagram for 4-polytopes.
sage: P = Polyhedron(vertices=[[1,1,0,0], [1,2,0,0], ....: [2,1,0,0], [0,0,1,0], [0,0,0,1]]); P A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices sage: P.projection().tikz(output_type='TikzPicture') Traceback (most recent call last): ... NotImplementedError: The polytope has to live in 2 or 3 dimensions.
>>> from sage.all import * >>> P = Polyhedron(vertices=[[Integer(1),Integer(1),Integer(0),Integer(0)], [Integer(1),Integer(2),Integer(0),Integer(0)], ... [Integer(2),Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),Integer(0),Integer(1)]]); P A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices >>> P.projection().tikz(output_type='TikzPicture') Traceback (most recent call last): ... NotImplementedError: The polytope has to live in 2 or 3 dimensions.
P = Polyhedron(vertices=[[1,1,0,0], [1,2,0,0], [2,1,0,0], [0,0,1,0], [0,0,0,1]]); P P.projection().tikz(output_type='TikzPicture')Make it possible to draw 3-polytopes living in higher dimension.
- class sage.geometry.polyhedron.plot.ProjectionFuncSchlegel(facet, projection_point)[source]¶
Bases:
objectThe Schlegel projection from the given input point.
EXAMPLES:
sage: from sage.geometry.polyhedron.plot import ProjectionFuncSchlegel sage: fcube = polytopes.hypercube(4) sage: facet = fcube.facets()[0] sage: proj = ProjectionFuncSchlegel(facet,[0,-1.5,0,0]) sage: proj([0,0,0,0])[0] 1.0
>>> from sage.all import * >>> from sage.geometry.polyhedron.plot import ProjectionFuncSchlegel >>> fcube = polytopes.hypercube(Integer(4)) >>> facet = fcube.facets()[Integer(0)] >>> proj = ProjectionFuncSchlegel(facet,[Integer(0),-RealNumber('1.5'),Integer(0),Integer(0)]) >>> proj([Integer(0),Integer(0),Integer(0),Integer(0)])[Integer(0)] 1.0
from sage.geometry.polyhedron.plot import ProjectionFuncSchlegel fcube = polytopes.hypercube(4) facet = fcube.facets()[0] proj = ProjectionFuncSchlegel(facet,[0,-1.5,0,0]) proj([0,0,0,0])[0]
- class sage.geometry.polyhedron.plot.ProjectionFuncStereographic(projection_point)[source]¶
Bases:
objectThe stereographic (or perspective) projection onto a codimension-1 linear subspace with respect to a sphere centered at the origin.
EXAMPLES:
sage: from sage.geometry.polyhedron.plot import ProjectionFuncStereographic sage: cube = polytopes.hypercube(3).vertices() sage: proj = ProjectionFuncStereographic([1.2, 3.4, 5.6]) sage: ppoints = [proj(vector(x)) for x in cube] sage: ppoints[5] (-0.0918273..., -0.036375...)
>>> from sage.all import * >>> from sage.geometry.polyhedron.plot import ProjectionFuncStereographic >>> cube = polytopes.hypercube(Integer(3)).vertices() >>> proj = ProjectionFuncStereographic([RealNumber('1.2'), RealNumber('3.4'), RealNumber('5.6')]) >>> ppoints = [proj(vector(x)) for x in cube] >>> ppoints[Integer(5)] (-0.0918273..., -0.036375...)
from sage.geometry.polyhedron.plot import ProjectionFuncStereographic cube = polytopes.hypercube(3).vertices() proj = ProjectionFuncStereographic([1.2, 3.4, 5.6]) ppoints = [proj(vector(x)) for x in cube] ppoints[5]
- sage.geometry.polyhedron.plot.cyclic_sort_vertices_2d(Vlist)[source]¶
Return the vertices/rays in cyclic order if possible.
Note
This works if and only if each vertex/ray is adjacent to exactly two others. For example, any 2-dimensional polyhedron satisfies this.
See
vertex_adjacency_matrix()for a discussion of “adjacent”.EXAMPLES:
sage: from sage.geometry.polyhedron.plot import cyclic_sort_vertices_2d sage: square = Polyhedron([[1,0],[-1,0],[0,1],[0,-1]]) sage: vertices = [v for v in square.vertex_generator()] sage: vertices [A vertex at (-1, 0), A vertex at (0, -1), A vertex at (0, 1), A vertex at (1, 0)] sage: cyclic_sort_vertices_2d(vertices) [A vertex at (1, 0), A vertex at (0, -1), A vertex at (-1, 0), A vertex at (0, 1)]
>>> from sage.all import * >>> from sage.geometry.polyhedron.plot import cyclic_sort_vertices_2d >>> square = Polyhedron([[Integer(1),Integer(0)],[-Integer(1),Integer(0)],[Integer(0),Integer(1)],[Integer(0),-Integer(1)]]) >>> vertices = [v for v in square.vertex_generator()] >>> vertices [A vertex at (-1, 0), A vertex at (0, -1), A vertex at (0, 1), A vertex at (1, 0)] >>> cyclic_sort_vertices_2d(vertices) [A vertex at (1, 0), A vertex at (0, -1), A vertex at (-1, 0), A vertex at (0, 1)]
from sage.geometry.polyhedron.plot import cyclic_sort_vertices_2d square = Polyhedron([[1,0],[-1,0],[0,1],[0,-1]]) vertices = [v for v in square.vertex_generator()] vertices cyclic_sort_vertices_2d(vertices)
Rays are allowed, too:
sage: P = Polyhedron(vertices=[(0, 1), (1, 0), (2, 0), (3, 0), (4, 1)], rays=[(0,1)]) sage: P.adjacency_matrix() [0 1 0 1 0] [1 0 1 0 0] [0 1 0 0 1] [1 0 0 0 1] [0 0 1 1 0] sage: cyclic_sort_vertices_2d(P.Vrepresentation()) [A vertex at (3, 0), A vertex at (1, 0), A vertex at (0, 1), A ray in the direction (0, 1), A vertex at (4, 1)] sage: P = Polyhedron(vertices=[(0, 1), (1, 0), (2, 0), (3, 0), (4, 1)], rays=[(0,1), (1,1)]) sage: P.adjacency_matrix() [0 1 0 0 0] [1 0 1 0 0] [0 1 0 0 1] [0 0 0 0 1] [0 0 1 1 0] sage: cyclic_sort_vertices_2d(P.Vrepresentation()) [A ray in the direction (1, 1), A vertex at (3, 0), A vertex at (1, 0), A vertex at (0, 1), A ray in the direction (0, 1)] sage: P = Polyhedron(vertices=[(1,2)], rays=[(0,1)], lines=[(1,0)]) sage: P.adjacency_matrix() [0 0 1] [0 0 0] [1 0 0] sage: cyclic_sort_vertices_2d(P.Vrepresentation()) [A vertex at (0, 2), A line in the direction (1, 0), A ray in the direction (0, 1)]
>>> from sage.all import * >>> P = Polyhedron(vertices=[(Integer(0), Integer(1)), (Integer(1), Integer(0)), (Integer(2), Integer(0)), (Integer(3), Integer(0)), (Integer(4), Integer(1))], rays=[(Integer(0),Integer(1))]) >>> P.adjacency_matrix() [0 1 0 1 0] [1 0 1 0 0] [0 1 0 0 1] [1 0 0 0 1] [0 0 1 1 0] >>> cyclic_sort_vertices_2d(P.Vrepresentation()) [A vertex at (3, 0), A vertex at (1, 0), A vertex at (0, 1), A ray in the direction (0, 1), A vertex at (4, 1)] >>> P = Polyhedron(vertices=[(Integer(0), Integer(1)), (Integer(1), Integer(0)), (Integer(2), Integer(0)), (Integer(3), Integer(0)), (Integer(4), Integer(1))], rays=[(Integer(0),Integer(1)), (Integer(1),Integer(1))]) >>> P.adjacency_matrix() [0 1 0 0 0] [1 0 1 0 0] [0 1 0 0 1] [0 0 0 0 1] [0 0 1 1 0] >>> cyclic_sort_vertices_2d(P.Vrepresentation()) [A ray in the direction (1, 1), A vertex at (3, 0), A vertex at (1, 0), A vertex at (0, 1), A ray in the direction (0, 1)] >>> P = Polyhedron(vertices=[(Integer(1),Integer(2))], rays=[(Integer(0),Integer(1))], lines=[(Integer(1),Integer(0))]) >>> P.adjacency_matrix() [0 0 1] [0 0 0] [1 0 0] >>> cyclic_sort_vertices_2d(P.Vrepresentation()) [A vertex at (0, 2), A line in the direction (1, 0), A ray in the direction (0, 1)]
P = Polyhedron(vertices=[(0, 1), (1, 0), (2, 0), (3, 0), (4, 1)], rays=[(0,1)]) P.adjacency_matrix() cyclic_sort_vertices_2d(P.Vrepresentation()) P = Polyhedron(vertices=[(0, 1), (1, 0), (2, 0), (3, 0), (4, 1)], rays=[(0,1), (1,1)]) P.adjacency_matrix() cyclic_sort_vertices_2d(P.Vrepresentation()) P = Polyhedron(vertices=[(1,2)], rays=[(0,1)], lines=[(1,0)]) P.adjacency_matrix() cyclic_sort_vertices_2d(P.Vrepresentation())
- sage.geometry.polyhedron.plot.projection_func_identity(x)[source]¶
The identity projection.
EXAMPLES:
sage: from sage.geometry.polyhedron.plot import projection_func_identity sage: projection_func_identity((1,2,3)) [1, 2, 3]
>>> from sage.all import * >>> from sage.geometry.polyhedron.plot import projection_func_identity >>> projection_func_identity((Integer(1),Integer(2),Integer(3))) [1, 2, 3]
from sage.geometry.polyhedron.plot import projection_func_identity projection_func_identity((1,2,3))