Base class for polyhedra: Methods for plotting and affine hull projection#
- class sage.geometry.polyhedron.base6.Polyhedron_base6(parent, Vrep, Hrep, Vrep_minimal=None, Hrep_minimal=None, pref_rep=None, mutable=False, **kwds)#
Bases:
Polyhedron_base5
Methods related to plotting including affine hull projection.
- affine_hull(*args, **kwds)#
Return the affine hull of
self
as a polyhedron.EXAMPLES:
sage: half_plane_in_space = Polyhedron(ieqs=[(0,1,0,0)], eqns=[(0,0,0,1)]) sage: half_plane_in_space.affine_hull().Hrepresentation() (An equation (0, 0, 1) x + 0 == 0,) sage: polytopes.cube().affine_hull().is_universe() True
- affine_hull_manifold(name=None, latex_name=None, start_index=0, ambient_space=None, ambient_chart=None, names=None, **kwds)#
Return the affine hull of
self
as a manifold.If
self
is full-dimensional, it is just the ambient Euclidean space. Otherwise, it is a Riemannian submanifold of the ambient Euclidean space.INPUT:
ambient_space
– aEuclideanSpace
of the ambient dimension (default: the manifold ofambient_chart
, if provided; otherwise, a new instance ofEuclideanSpace
).ambient_chart
– a chart onambient_space
.names
– names for the coordinates on the affine hull.optional arguments accepted by
affine_hull_projection()
.
The default chart is determined by the optional arguments of
affine_hull_projection()
.EXAMPLES:
sage: triangle = Polyhedron([(1,0,0), (0,1,0), (0,0,1)]); triangle A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 3 vertices sage: A = triangle.affine_hull_manifold(name='A'); A 2-dimensional Riemannian submanifold A embedded in the Euclidean space E^3 sage: A.embedding().display() A → E^3 (x0, x1) ↦ (x, y, z) = (t0 + x0, t0 + x1, t0 - x0 - x1 + 1) sage: A.embedding().inverse().display() E^3 → A (x, y, z) ↦ (x0, x1) = (x, y) sage: A.adapted_chart() [Chart (E^3, (x0_E3, x1_E3, t0_E3))] sage: A.normal().display() n = 1/3*sqrt(3) e_x + 1/3*sqrt(3) e_y + 1/3*sqrt(3) e_z sage: A.induced_metric() # Need to call this before volume_form Riemannian metric gamma on the 2-dimensional Riemannian submanifold A embedded in the Euclidean space E^3 sage: A.volume_form() 2-form eps_gamma on the 2-dimensional Riemannian submanifold A embedded in the Euclidean space E^3
Orthogonal version:
sage: A = triangle.affine_hull_manifold(name='A', orthogonal=True); A 2-dimensional Riemannian submanifold A embedded in the Euclidean space E^3 sage: A.embedding().display() A → E^3 (x0, x1) ↦ (x, y, z) = (t0 - 1/2*x0 - 1/3*x1 + 1, t0 + 1/2*x0 - 1/3*x1, t0 + 2/3*x1) sage: A.embedding().inverse().display() E^3 → A (x, y, z) ↦ (x0, x1) = (-x + y + 1, -1/2*x - 1/2*y + z + 1/2)
Arrangement of affine hull of facets:
sage: D = polytopes.dodecahedron() # optional - sage.rings.number_field sage: E3 = EuclideanSpace(3) # optional - sage.rings.number_field sage: submanifolds = [ # optional - sage.rings.number_field ....: F.as_polyhedron().affine_hull_manifold(name=f'F{i}', orthogonal=True, ambient_space=E3) ....: for i, F in enumerate(D.facets())] sage: sum(FM.plot({}, srange(-2, 2, 0.1), srange(-2, 2, 0.1), opacity=0.2) # not tested # optional - sage.plot # optional - sage.rings.number_field ....: for FM in submanifolds) + D.plot() Graphics3d Object
Full-dimensional case:
sage: cube = polytopes.cube(); cube A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices sage: cube.affine_hull_manifold() Euclidean space E^3
- affine_hull_projection(as_polyhedron, as_affine_map=None, orthogonal=False, orthonormal=False, extend=False, minimal=False, return_all_data=False, as_convex_set=False)#
Return the polyhedron projected into its affine hull.
Each polyhedron is contained in some smallest affine subspace (possibly the entire ambient space) – its affine hull. We provide an affine linear map that projects the ambient space of the polyhedron to the standard Euclidean space of dimension of the polyhedron, which restricts to a bijection from the affine hull.
The projection map is not unique; some parameters control the choice of the map. Other parameters control the output of the function.
INPUT:
as_polyhedron
(oras_convex_set
) – (boolean or the defaultNone
) andas_affine_map
– (boolean, defaultFalse
) control the outputThe default
as_polyhedron=None
translates toas_polyhedron=not as_affine_map
, therefore toas_polyhedron=True
if nothing is specified.If exactly one of either
as_polyhedron
oras_affine_map
is set, then either a polyhedron or the affine transformation is returned. The affine transformation sends the embedded polytope to a fulldimensional one. It is given as a pair(A, b)
, where A is a linear transformation and \(b\) is a vector, and the affine transformation sendsv
toA(v)+b
.If both
as_polyhedron
andas_affine_map
are set, then both are returned, encapsulated in an instance ofAffineHullProjectionData
.return_all_data
– (boolean, defaultFalse
)If set, then
as_polyhedron
andas_affine_map
will set (possibly overridden) and additional (internal) data concerning the transformation is returned. Everything is encapsulated in an instance ofAffineHullProjectionData
in this case.orthogonal
– boolean (default:False
); ifTrue
, provide an orthogonal transformation.orthonormal
– boolean (default:False
); ifTrue
, provide an orthonormal transformation. If the base ring does not provide the necessary square roots, the extend parameter needs to be set toTrue
.extend
– boolean (default:False
); ifTrue
, allow base ring to be extended if necessary. This becomes relevant when requiring an orthonormal transformation.minimal
– boolean (default:False
); ifTrue
, when doing an extension, it computes the minimal base ring of the extension, otherwise the base ring isAA
.
OUTPUT:
A full-dimensional polyhedron or an affine transformation, depending on the parameters
as_polyhedron
andas_affine_map
, or an instance ofAffineHullProjectionData
containing all data (parameterreturn_all_data
).If the output is an instance of
AffineHullProjectionData
, the following fields may be set:image
– the projection of the original polyhedronprojection_map
– the affine map as a pair whose first component is a linear transformation and its second component a shift; see above.section_map
– an affine map as a pair whose first component is a linear transformation and its second component a shift. It maps the codomain ofaffine_map
to the affine hull ofself
. It is a right inverse ofprojection_map
.
Note that all of these data are compatible.
Todo
make the parameters
orthogonal
andorthonormal
work with unbounded polyhedra.
EXAMPLES:
sage: triangle = Polyhedron([(1,0,0), (0,1,0), (0,0,1)]); triangle A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 3 vertices sage: triangle.affine_hull_projection() A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices sage: half3d = Polyhedron(vertices=[(3,2,1)], rays=[(1,0,0)]) sage: half3d.affine_hull_projection().Vrepresentation() (A ray in the direction (1), A vertex at (3))
The resulting affine hulls depend on the parameter
orthogonal
andorthonormal
:sage: L = Polyhedron([[1,0],[0,1]]); L A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices sage: A = L.affine_hull_projection(); A A 1-dimensional polyhedron in ZZ^1 defined as the convex hull of 2 vertices sage: A.vertices() (A vertex at (0), A vertex at (1)) sage: A = L.affine_hull_projection(orthogonal=True); A A 1-dimensional polyhedron in QQ^1 defined as the convex hull of 2 vertices sage: A.vertices() (A vertex at (0), A vertex at (2)) sage: A = L.affine_hull_projection(orthonormal=True) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: the base ring needs to be extended; try with "extend=True" sage: A = L.affine_hull_projection(orthonormal=True, extend=True); A # optional - sage.rings.number_field A 1-dimensional polyhedron in AA^1 defined as the convex hull of 2 vertices sage: A.vertices() # optional - sage.rings.number_field (A vertex at (1.414213562373095?), A vertex at (0.?e-18))
More generally:
sage: S = polytopes.simplex(); S A 3-dimensional polyhedron in ZZ^4 defined as the convex hull of 4 vertices sage: S.vertices() (A vertex at (0, 0, 0, 1), A vertex at (0, 0, 1, 0), A vertex at (0, 1, 0, 0), A vertex at (1, 0, 0, 0)) sage: A = S.affine_hull_projection(); A A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 4 vertices sage: A.vertices() (A vertex at (0, 0, 0), A vertex at (0, 0, 1), A vertex at (0, 1, 0), A vertex at (1, 0, 0)) sage: A = S.affine_hull_projection(orthogonal=True); A A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices sage: A.vertices() (A vertex at (0, 0, 0), A vertex at (2, 0, 0), A vertex at (1, 3/2, 0), A vertex at (1, 1/2, 4/3)) sage: A = S.affine_hull_projection(orthonormal=True, extend=True); A # optional - sage.rings.number_field A 3-dimensional polyhedron in AA^3 defined as the convex hull of 4 vertices sage: A.vertices() # optional - sage.rings.number_field (A vertex at (0.7071067811865475?, 0.4082482904638630?, 1.154700538379252?), A vertex at (0.7071067811865475?, 1.224744871391589?, 0.?e-18), A vertex at (1.414213562373095?, 0.?e-18, 0.?e-18), A vertex at (0.?e-18, 0.?e-18, 0.?e-18))
With the parameter
minimal
one can get a minimal base ring:sage: s = polytopes.simplex(3) sage: s_AA = s.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field sage: s_AA.base_ring() # optional - sage.rings.number_field Algebraic Real Field sage: s_full = s.affine_hull_projection(orthonormal=True, extend=True, minimal=True) # optional - sage.rings.number_field sage: s_full.base_ring() # optional - sage.rings.number_field Number Field in a with defining polynomial y^4 - 4*y^2 + 1 with a = 0.5176380902050415?
More examples with the
orthonormal
parameter:sage: P = polytopes.permutahedron(3); P # optional - sage.combinat # optional - sage.rings.number_field A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 6 vertices sage: set([F.as_polyhedron().affine_hull_projection(orthonormal=True, extend=True).volume() for F in P.affine_hull_projection().faces(1)]) == {1, sqrt(AA(2))} # optional - sage.combinat # optional - sage.rings.number_field True sage: set([F.as_polyhedron().affine_hull_projection(orthonormal=True, extend=True).volume() for F in P.affine_hull_projection(orthonormal=True, extend=True).faces(1)]) == {sqrt(AA(2))} # optional - sage.combinat # optional - sage.rings.number_field True sage: D = polytopes.dodecahedron() # optional - sage.rings.number_field sage: F = D.faces(2)[0].as_polyhedron() # optional - sage.rings.number_field sage: F.affine_hull_projection(orthogonal=True) # optional - sage.rings.number_field A 2-dimensional polyhedron in (Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?)^2 defined as the convex hull of 5 vertices sage: F.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field A 2-dimensional polyhedron in AA^2 defined as the convex hull of 5 vertices sage: K.<sqrt2> = QuadraticField(2) # optional - sage.rings.number_field sage: P = Polyhedron([2*[K.zero()],2*[sqrt2]]); P # optional - sage.rings.number_field A 1-dimensional polyhedron in (Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095?)^2 defined as the convex hull of 2 vertices sage: P.vertices() # optional - sage.rings.number_field (A vertex at (0, 0), A vertex at (sqrt2, sqrt2)) sage: A = P.affine_hull_projection(orthonormal=True); A # optional - sage.rings.number_field A 1-dimensional polyhedron in (Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095?)^1 defined as the convex hull of 2 vertices sage: A.vertices() # optional - sage.rings.number_field (A vertex at (0), A vertex at (2)) sage: K.<sqrt3> = QuadraticField(3) # optional - sage.rings.number_field sage: P = Polyhedron([2*[K.zero()],2*[sqrt3]]); P # optional - sage.rings.number_field A 1-dimensional polyhedron in (Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878?)^2 defined as the convex hull of 2 vertices sage: P.vertices() # optional - sage.rings.number_field (A vertex at (0, 0), A vertex at (sqrt3, sqrt3)) sage: A = P.affine_hull_projection(orthonormal=True) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: the base ring needs to be extended; try with "extend=True" sage: A = P.affine_hull_projection(orthonormal=True, extend=True); A # optional - sage.rings.number_field A 1-dimensional polyhedron in AA^1 defined as the convex hull of 2 vertices sage: A.vertices() # optional - sage.rings.number_field (A vertex at (0), A vertex at (2.449489742783178?)) sage: sqrt(6).n() # optional - sage.rings.number_field 2.44948974278318
The affine hull is combinatorially equivalent to the input:
sage: P.is_combinatorially_isomorphic(P.affine_hull_projection()) # optional - sage.rings.number_field True sage: P.is_combinatorially_isomorphic(P.affine_hull_projection(orthogonal=True)) # optional - sage.rings.number_field True sage: P.is_combinatorially_isomorphic(P.affine_hull_projection(orthonormal=True, extend=True)) # optional - sage.rings.number_field True
The
orthonormal=True
parameter preserves volumes; it provides an isometric copy of the polyhedron:sage: Pentagon = polytopes.dodecahedron().faces(2)[0].as_polyhedron() # optional - sage.rings.number_field sage: P = Pentagon.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field sage: _, c= P.is_inscribed(certificate=True) # optional - sage.rings.number_field sage: c # optional - sage.rings.number_field (0.4721359549995794?, 0.6498393924658126?) sage: circumradius = (c-vector(P.vertices()[0])).norm() # optional - sage.rings.number_field sage: p = polytopes.regular_polygon(5) # optional - sage.rings.number_field sage: p.volume() # optional - sage.rings.number_field 2.377641290737884? sage: P.volume() # optional - sage.rings.number_field 1.53406271079097? sage: p.volume()*circumradius^2 # optional - sage.rings.number_field 1.534062710790965? sage: P.volume() == p.volume()*circumradius^2 # optional - sage.rings.number_field True
One can also use
orthogonal
parameter to calculate volumes; in this case we don’t need to switch base rings. One has to divide by the square root of the determinant of the linear part of the affine transformation times its transpose:sage: Pentagon = polytopes.dodecahedron().faces(2)[0].as_polyhedron() # optional - sage.rings.number_field sage: Pnormal = Pentagon.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field sage: Pgonal = Pentagon.affine_hull_projection(orthogonal=True) # optional - sage.rings.number_field sage: A, b = Pentagon.affine_hull_projection(orthogonal=True, as_affine_map=True) # optional - sage.rings.number_field sage: Adet = (A.matrix().transpose()*A.matrix()).det() # optional - sage.rings.number_field sage: Pnormal.volume() # optional - sage.rings.number_field 1.53406271079097? sage: Pgonal.volume()/Adet.sqrt(extend=True) # optional - sage.rings.number_field -80*(55*sqrt(5) - 123)/sqrt(-6368*sqrt(5) + 14240) sage: Pgonal.volume()/AA(Adet).sqrt().n(digits=20) # optional - sage.rings.number_field 1.5340627107909646813 sage: AA(Pgonal.volume()^2) == (Pnormal.volume()^2)*AA(Adet) # optional - sage.rings.number_field True
Another example with
as_affine_map=True
:sage: P = polytopes.permutahedron(4) # optional - sage.combinat # optional - sage.rings.number_field sage: A, b = P.affine_hull_projection(orthonormal=True, as_affine_map=True, extend=True) # optional - sage.combinat # optional - sage.rings.number_field sage: Q = P.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.combinat # optional - sage.rings.number_field sage: Q.center() # optional - sage.combinat # optional - sage.rings.number_field (0.7071067811865475?, 1.224744871391589?, 1.732050807568878?) sage: A(P.center()) + b == Q.center() # optional - sage.combinat # optional - sage.rings.number_field True
For unbounded, non full-dimensional polyhedra, the
orthogonal=True
andorthonormal=True
is not implemented:sage: P = Polyhedron(ieqs=[[0, 1, 0], [0, 0, 1], [0, 0, -1]]); P A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 ray sage: P.is_compact() False sage: P.is_full_dimensional() False sage: P.affine_hull_projection(orthogonal=True) Traceback (most recent call last): ... NotImplementedError: "orthogonal=True" and "orthonormal=True" work only for compact polyhedra sage: P.affine_hull_projection(orthonormal=True) Traceback (most recent call last): ... NotImplementedError: "orthogonal=True" and "orthonormal=True" work only for compact polyhedra
Setting
as_affine_map
toTrue
withoutorthogonal
ororthonormal
set toTrue
:sage: S = polytopes.simplex() sage: S.affine_hull_projection(as_affine_map=True) (Vector space morphism represented by the matrix: [1 0 0] [0 1 0] [0 0 1] [0 0 0] Domain: Vector space of dimension 4 over Rational Field Codomain: Vector space of dimension 3 over Rational Field, (0, 0, 0))
If the polyhedron is full-dimensional, it is returned:
sage: polytopes.cube().affine_hull_projection() A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices sage: polytopes.cube().affine_hull_projection(as_affine_map=True) (Vector space morphism represented by the matrix: [1 0 0] [0 1 0] [0 0 1] Domain: Vector space of dimension 3 over Rational Field Codomain: Vector space of dimension 3 over Rational Field, (0, 0, 0))
Return polyhedron and affine map:
sage: S = polytopes.simplex(2) sage: data = S.affine_hull_projection(orthogonal=True, ....: as_polyhedron=True, ....: as_affine_map=True); data AffineHullProjectionData(image=A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices, projection_linear_map=Vector space morphism represented by the matrix: [ -1 -1/2] [ 1 -1/2] [ 0 1] Domain: Vector space of dimension 3 over Rational Field Codomain: Vector space of dimension 2 over Rational Field, projection_translation=(1, 1/2), section_linear_map=None, section_translation=None)
Return all data:
sage: data = S.affine_hull_projection(orthogonal=True, return_all_data=True); data AffineHullProjectionData(image=A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices, projection_linear_map=Vector space morphism represented by the matrix: [ -1 -1/2] [ 1 -1/2] [ 0 1] Domain: Vector space of dimension 3 over Rational Field Codomain: Vector space of dimension 2 over Rational Field, projection_translation=(1, 1/2), section_linear_map=Vector space morphism represented by the matrix: [-1/2 1/2 0] [-1/3 -1/3 2/3] Domain: Vector space of dimension 2 over Rational Field Codomain: Vector space of dimension 3 over Rational Field, section_translation=(1, 0, 0))
The section map is a right inverse of the projection map:
sage: data.image.linear_transformation(data.section_linear_map.matrix().transpose()) + data.section_translation == S True
Same without
orthogonal=True
:sage: data = S.affine_hull_projection(return_all_data=True); data AffineHullProjectionData(image=A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices, projection_linear_map=Vector space morphism represented by the matrix: [1 0] [0 1] [0 0] Domain: Vector space of dimension 3 over Rational Field Codomain: Vector space of dimension 2 over Rational Field, projection_translation=(0, 0), section_linear_map=Vector space morphism represented by the matrix: [ 1 0 -1] [ 0 1 -1] Domain: Vector space of dimension 2 over Rational Field Codomain: Vector space of dimension 3 over Rational Field, section_translation=(0, 0, 1)) sage: data.image.linear_transformation(data.section_linear_map.matrix().transpose()) + data.section_translation == S True
sage: P0 = Polyhedron( ....: ieqs=[(0, -1, 0, 1, 1, 1), (0, 1, 1, 0, -1, -1), (0, -1, 1, 1, 0, 0), ....: (0, 1, 0, 0, 0, 0), (0, 0, 1, 1, -1, -1), (0, 0, 0, 0, 0, 1), ....: (0, 0, 0, 0, 1, 0), (0, 0, 0, 1, 0, -1), (0, 0, 1, 0, 0, 0)]) sage: P = P0.intersection(Polyhedron(eqns=[(-1, 1, 1, 1, 1, 1)])) sage: P.dim() 4 sage: P.affine_hull_projection(orthogonal=True, as_affine_map=True)[0] Vector space morphism represented by the matrix: [ 0 0 0 1/3] [ -2/3 -1/6 0 -1/12] [ 1/3 -1/6 1/2 -1/12] [ 0 1/2 0 -1/12] [ 1/3 -1/6 -1/2 -1/12] Domain: Vector space of dimension 5 over Rational Field Codomain: Vector space of dimension 4 over Rational Field
- gale_transform()#
Return the Gale transform of a polytope as described in the reference below.
OUTPUT:
A list of vectors, the Gale transform. The dimension is the dimension of the affine dependencies of the vertices of the polytope.
EXAMPLES:
This is from the reference, for a triangular prism:
sage: p = Polyhedron(vertices = [[0,0],[0,1],[1,0]]) sage: p2 = p.prism() sage: p2.gale_transform() ((-1, 0), (0, -1), (1, 1), (-1, -1), (1, 0), (0, 1))
REFERENCES:
Lectures in Geometric Combinatorics, R.R.Thomas, 2006, AMS Press.
See also
gale_transform_to_polyhedron()
.
- plot(point=None, line=None, polygon=None, wireframe='blue', fill='green', position=None, orthonormal=True, **kwds)#
Return a graphical representation.
INPUT:
point
,line
,polygon
– Parameters to pass to point (0d), line (1d), and polygon (2d) plot commands. Allowed values are:A Python dictionary to be passed as keywords to the plot commands.
A string or triple of numbers: The color. This is equivalent to passing the dictionary
{'color':...}
.False
: Switches off the drawing of the corresponding graphics object
wireframe
,fill
– Similar topoint
,line
, andpolygon
, butfill
is used for the graphics objects in the dimension of the polytope (or of dimension 2 for higher dimensional polytopes) andwireframe
is used for all lower-dimensional graphics objects (default: ‘green’ forfill
and ‘blue’ forwireframe
)position
– positive number; the position to take the projection point in Schlegel diagrams.orthonormal
– Boolean (default: True); whether to use orthonormal projections.**kwds
– optional keyword parameters that are passed to all graphics objects.
OUTPUT:
A (multipart) graphics object.
EXAMPLES:
sage: square = polytopes.hypercube(2) sage: point = Polyhedron([[1,1]]) sage: line = Polyhedron([[1,1],[2,1]]) sage: cube = polytopes.hypercube(3) sage: hypercube = polytopes.hypercube(4)
By default, the wireframe is rendered in blue and the fill in green:
sage: square.plot() # optional - sage.plot Graphics object consisting of 6 graphics primitives sage: point.plot() # optional - sage.plot Graphics object consisting of 1 graphics primitive sage: line.plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives sage: cube.plot() # optional - sage.plot Graphics3d Object sage: hypercube.plot() # optional - sage.plot Graphics3d Object
Draw the lines in red and nothing else:
sage: square.plot(point=False, line='red', polygon=False) # optional - sage.plot Graphics object consisting of 4 graphics primitives sage: point.plot(point=False, line='red', polygon=False) # optional - sage.plot Graphics object consisting of 0 graphics primitives sage: line.plot(point=False, line='red', polygon=False) # optional - sage.plot Graphics object consisting of 1 graphics primitive sage: cube.plot(point=False, line='red', polygon=False) # optional - sage.plot Graphics3d Object sage: hypercube.plot(point=False, line='red', polygon=False) # optional - sage.plot Graphics3d Object
Draw points in red, no lines, and a blue polygon:
sage: square.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot Graphics object consisting of 2 graphics primitives sage: point.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot Graphics object consisting of 1 graphics primitive sage: line.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot Graphics object consisting of 1 graphics primitive sage: cube.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot Graphics3d Object sage: hypercube.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot Graphics3d Object
If we instead use the
fill
andwireframe
options, the coloring depends on the dimension of the object:sage: square.plot(fill='green', wireframe='red') # optional - sage.plot Graphics object consisting of 6 graphics primitives sage: point.plot(fill='green', wireframe='red') # optional - sage.plot Graphics object consisting of 1 graphics primitive sage: line.plot(fill='green', wireframe='red') # optional - sage.plot Graphics object consisting of 2 graphics primitives sage: cube.plot(fill='green', wireframe='red') # optional - sage.plot Graphics3d Object sage: hypercube.plot(fill='green', wireframe='red') # optional - sage.plot Graphics3d Object
It is possible to draw polyhedra up to dimension 4, no matter what the ambient dimension is:
sage: hcube = polytopes.hypercube(5) sage: facet = hcube.facets()[0].as_polyhedron();facet A 4-dimensional polyhedron in ZZ^5 defined as the convex hull of 16 vertices sage: facet.plot() # optional - sage.plot Graphics3d Object
For a 3d plot, we may draw the polygons with rainbow colors, using any of the following ways:
sage: cube.plot(polygon='rainbow') # optional - sage.plot Graphics3d Object sage: cube.plot(polygon={'color':'rainbow'}) # optional - sage.plot Graphics3d Object sage: cube.plot(fill='rainbow') # optional - sage.plot Graphics3d Object
For a 3d plot, the size of a point, the thickness of a line and the width of an arrow are controlled by the respective parameters:
sage: prism = Polyhedron(vertices=[[0,0,0],[1,0,0],[0,1,0]], rays=[[0,0,1]]) sage: prism.plot(size=20, thickness=30, width=1) # optional - sage.plot Graphics3d Object sage: prism.plot(point={'size':20, 'color':'black'}, line={'thickness':30, 'width':1, 'color':'black'}, polygon='rainbow') # optional - sage.plot Graphics3d Object
- projection(projection=None)#
Return a projection object.
INPUT:
proj
– a projection function
OUTPUT:
The identity projection. This is useful for plotting polyhedra.
See also
schlegel_projection()
for a more interesting projection.EXAMPLES:
sage: p = polytopes.hypercube(3) sage: proj = p.projection() sage: proj The projection of a polyhedron into 3 dimensions
- render_solid(**kwds)#
Return a solid rendering of a 2- or 3-d polytope.
EXAMPLES:
sage: p = polytopes.hypercube(3) sage: p_solid = p.render_solid(opacity = .7) sage: type(p_solid) <class 'sage.plot.plot3d.index_face_set.IndexFaceSet'>
- render_wireframe(**kwds)#
For polytopes in 2 or 3 dimensions, return the edges as a list of lines.
EXAMPLES:
sage: p = Polyhedron([[1,2,],[1,1],[0,0]]) sage: p_wireframe = p.render_wireframe() sage: p_wireframe._objects [Line defined by 2 points, Line defined by 2 points, Line defined by 2 points]
- schlegel_projection(facet=None, position=None)#
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
– aPolyhedronFace
. 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. Default is \(1\). If the given value is too large, an error is returned.
OUTPUT:
A
Projection
object.EXAMPLES:
sage: p = polytopes.hypercube(3) sage: sch_proj = p.schlegel_projection() sage: schlegel_edge_indices = sch_proj.lines sage: schlegel_edges = [sch_proj.coordinates_of(x) for x in schlegel_edge_indices] sage: len([x for x in schlegel_edges if x[0][0] > 0]) 8
The Schlegel projection preserves the convexity of facets, see trac ticket #30015:
sage: fcube = polytopes.hypercube(4) sage: tfcube = fcube.face_truncation(fcube.faces(0)[0]) sage: tfcube.facets()[-1] A 3-dimensional face of a Polyhedron in QQ^4 defined as the convex hull of 8 vertices sage: sp = tfcube.schlegel_projection(tfcube.facets()[-1]) sage: sp.plot() # optional - sage.plot Graphics3d Object
The same truncated cube but see inside the tetrahedral facet:
sage: tfcube.facets()[4] A 3-dimensional face of a Polyhedron in QQ^4 defined as the convex hull of 4 vertices sage: sp = tfcube.schlegel_projection(tfcube.facets()[4]) sage: sp.plot() # optional - sage.plot Graphics3d Object
A different values of
position
changes the projection:sage: sp = tfcube.schlegel_projection(tfcube.facets()[4],1/2) sage: sp.plot() # optional - sage.plot Graphics3d Object sage: sp = tfcube.schlegel_projection(tfcube.facets()[4],4) sage: sp.plot() # optional - sage.plot Graphics3d Object
A value which is too large give a projection point that sees more than one facet resulting in a error:
sage: sp = tfcube.schlegel_projection(tfcube.facets()[4],5) Traceback (most recent call last): ... ValueError: the chosen position is too large
- show(**kwds)#
Display graphics immediately
This method attempts to display the graphics immediately, without waiting for the currently running code (if any) to return to the command line. Be careful, calling it from within a loop will potentially launch a large number of external viewer programs.
INPUT:
kwds
– optional keyword arguments. Seeplot()
for the description of available options.
OUTPUT:
This method does not return anything. Use
plot()
if you want to generate a graphics object that can be saved or further transformed.EXAMPLES:
sage: square = polytopes.hypercube(2) sage: square.show(point='red') # optional - sage.plot
- 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=None)#
Return a tikz picture of
self
as a string or as aTikzPicture
according to a projectionview
and an angleangle
obtained via the threejs viewer.self
must be bounded.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) specifying the scaling of the tikz picture.edge_color
- string (default: ‘blue!95!black’) representing colors which tikz recognize.facet_color
- string (default: ‘blue!95!black’) representing colors which tikz recognize.vertex_color
- string (default: ‘green’) representing colors which tikz recognize.opacity
- real number (default: 0.8) between 0 and 1 giving the opacity of the front facets.axis
- Boolean (default: False) draw the axes at the origin or not.output_type
- string (default:None
), valid values areNone
(deprecated),'LatexExpr'
and'TikzPicture'
, whether to return a LatexExpr object (which inherits from Python str) or aTikzPicture
object from modulesage.misc.latex_standalone
OUTPUT:
LatexExpr object or TikzPicture object
Note
This is a wrapper of a method of the projection object
self.projection()
. Seetikz()
for more detail.The inputs
view
andangle
can 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.tikz([x,y,z],angle)
.The inputs
view
andangle
can 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} Scale
The
view
is then [x,y,z] andangle
is angle. The following number is the scale.Jmol performs a rotation of
angle
degrees along the vector [x,y,z] and show the result from the z-axis.EXAMPLES:
sage: co = polytopes.cuboctahedron() sage: Img = co.tikz([0,0,1], 0, output_type='TikzPicture') sage: Img \documentclass[tikz]{standalone} \begin{document} \begin{tikzpicture}% [x={(1.000000cm, 0.000000cm)}, y={(0.000000cm, 1.000000cm)}, z={(0.000000cm, 0.000000cm)}, scale=1.000000, ... Use print to see the full content. ... \node[vertex] at (1.00000, 0.00000, 1.00000) {}; \node[vertex] at (1.00000, 1.00000, 0.00000) {}; %% %% \end{tikzpicture} \end{document} sage: print('\n'.join(Img.content().splitlines()[12:21])) %% with the command: ._tikz_3d_in_3d and parameters: %% 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 sage: print('\n'.join(Img.content().splitlines()[22:26])) %% Coordinate of the vertices: %% \coordinate (-1.00000, -1.00000, 0.00000) at (-1.00000, -1.00000, 0.00000); \coordinate (-1.00000, 0.00000, -1.00000) at (-1.00000, 0.00000, -1.00000);
When output type is a
sage.misc.latex_standalone.TikzPicture
:sage: co = polytopes.cuboctahedron() sage: t = co.tikz([674,108,-731], 112, output_type='TikzPicture') sage: t \documentclass[tikz]{standalone} \begin{document} \begin{tikzpicture}% [x={(0.249656cm, -0.577639cm)}, y={(0.777700cm, -0.358578cm)}, z={(-0.576936cm, -0.733318cm)}, scale=1.000000, ... Use print to see the full content. ... \node[vertex] at (1.00000, 0.00000, 1.00000) {}; \node[vertex] at (1.00000, 1.00000, 0.00000) {}; %% %% \end{tikzpicture} \end{document} sage: path_to_file = t.pdf() # not tested