Skip to content

Commit

Permalink
sagemathgh-39597: extract _front_back_facets method out of _tikz_3d_i…
Browse files Browse the repository at this point in the history
…n_3d polyhedron method

    
The code of the method `_tikz_3d_in_3d` is long. Also, the front and
back facets it computes for the projection of a polyhedron is
interesting by itself. Personally, I need this information in order to
define a polyhedron exchange transformation out of the projection of a
zonotope.

In this PR, we extract a `_front_back_facets` method out of the
`_tikz_3d_in_3d` method in the class Projection of a polyhedron.

Meanwhile, we also improve the SageMath/Python code. For instance:

```diff
-        for index_facet in range(len(facets)):
-            A = facets[index_facet].vector()[1:]
+        for index_facet,f in enumerate(facet_ineqs):
+           A = f.A()
```

This was done during Sage Days 128 with Jean-Philippe Labbé.

### 📝 Checklist

- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation and checked the documentation
preview.
    
URL: sagemath#39597
Reported by: Sébastien Labbé
Reviewer(s): Frédéric Chapoton, Sébastien Labbé
  • Loading branch information
Release Manager committed Mar 2, 2025
2 parents 2a1ce6e + 82f898b commit f635f8d
Showing 1 changed file with 56 additions and 28 deletions.
84 changes: 56 additions & 28 deletions src/sage/geometry/polyhedron/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -1815,33 +1815,7 @@ def _tikz_3d_in_3d(self, view, angle, scale, edge_color,
proj_vector = (rot**(-1))*vector(RDF, [0, 0, 1])

# First compute the back and front vertices and facets
facets = self.face_inequalities
front_facets = []
back_facets = []
for index_facet in range(len(facets)):
A = facets[index_facet].vector()[1:]
B = facets[index_facet].vector()[0]
if A*(2000*proj_vector)+B < 0:
front_facets += [index_facet]
else:
back_facets += [index_facet]

vertices = list(self.parent_polyhedron.Vrep_generator())
front_vertices = []
for index_facet in front_facets:
A = facets[index_facet].vector()[1:]
B = facets[index_facet].vector()[0]
for v in self.points:
if A*self.coords[v]+B < 0.0005 and v not in front_vertices:
front_vertices += [v]

back_vertices = []
for index_facet in back_facets:
A = facets[index_facet].vector()[1:]
B = facets[index_facet].vector()[0]
for v in self.points:
if A * self.coords[v] + B < 0.0005 and v not in back_vertices:
back_vertices += [v]
front_facets, back_facets, front_vertices, back_vertices = self._front_back_facets(proj_vector)

# Creates the nodes, coordinate and tag for every vertex of the polytope.
# The tag is used to draw the front facets later on.
Expand All @@ -1860,7 +1834,7 @@ def _tikz_3d_in_3d(self, view, angle, scale, edge_color,
dict_drawing[vert] = node, coord, tag

# Separate the edges between back and front

facets = self.face_inequalities
for index1, index2 in self.lines:
# v1 = self.coords[index1]
# v2 = self.coords[index2]
Expand Down Expand Up @@ -1933,6 +1907,7 @@ def _tikz_3d_in_3d(self, view, angle, scale, edge_color,

# Draw the facets in the front by going in cycles for every facet.
tikz_pic += '%%\n%%\n%% Drawing the facets\n%%\n'
vertices = self.parent_polyhedron.Vrep_generator()
vertex_to_index = {v: i for i, v in enumerate(vertices)}
for index_facet in front_facets:
cyclic_vert = cyclic_sort_vertices_2d(list(facets[index_facet].incident()))
Expand All @@ -1955,3 +1930,56 @@ def _tikz_3d_in_3d(self, view, angle, scale, edge_color,
tikz_pic += dict_drawing[v][0]
tikz_pic += '%%\n%%\n\\end{tikzpicture}'
return LatexExpr(tikz_pic)

def _front_back_facets(self, projection_vector):
r"""
Return the front/back vertices/facets of the projected polyhedron
with respect to the projection vector.
INPUT:
- ``projection_vector`` -- vector
EXAMPLES::
sage: # needs sage.plot sage.rings.number_field
sage: P = polytopes.small_rhombicuboctahedron()
sage: from sage.geometry.polyhedron.plot import Projection
sage: proj = Projection(P)
sage: v = (-0.544571767341018, 0.8192019648731899, 0.17986030958214505)
sage: v = vector(RDF, v)
sage: proj._front_back_facets(v)
([0, 2, 4, 5, 8, 9, 10, 17, 18, 19, 20, 22, 24],
[1, 3, 6, 7, 11, 12, 13, 14, 15, 16, 21, 23, 25],
[2, 3, 14, 15, 0, 12, 1, 4, 13, 16, 6, 7, 18, 19, 20, 21, 23],
[4, 9, 16, 21, 3, 5, 15, 17, 10, 22, 2, 6, 8, 7, 11, 20, 23])
"""
facet_ineqs = self.face_inequalities
front_facets = []
back_facets = []
for index_facet,f in enumerate(facet_ineqs):
A = f.A()
if A * projection_vector < 0:
front_facets.append(index_facet)
else:
back_facets.append(index_facet)

front_vertices = []
for index_facet in front_facets:
f_ineq = facet_ineqs[index_facet]
A = f_ineq.A()
b = f_ineq.b()
for v in self.points:
if A * self.coords[v] + b < 0.0005 and v not in front_vertices:
front_vertices.append(v)

back_vertices = []
for index_facet in back_facets:
f_ineq = facet_ineqs[index_facet]
A = f_ineq.A()
b = f_ineq.b()
for v in self.points:
if A * self.coords[v] + b < 0.0005 and v not in back_vertices:
back_vertices.append(v)

return front_facets, back_facets, front_vertices, back_vertices

0 comments on commit f635f8d

Please sign in to comment.