ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Sun, 08 Oct 2023 00:12:22 +0200Union of touching polyhedrahttps://ask.sagemath.org/question/55769/union-of-touching-polyhedra/Hi, I'm trying to do a union operation over multiple touching polyhedra into one but couldn't find how to achieve this with Sage. For example, how can I merge these two cubes and dissolve the interior face (the touching face):
# two cubes touching
cube_a = Polyhedron(vertices=[(0,0,0), (0,0,1), (0,1,0), (0,1,1), (1,0,0), (1,0,1), (1,1,0), (1,1,1)])
cube_b = Polyhedron(vertices=[(1,1/2,0), (1,1/2,1), (1,3/2,0), (1,3/2,1), (2,1/2,0), (2,1/2,1), (2,3/2,0), (2,3/2,1)])
# visualize
cube_a.plot() + cube_b.plot()
The polyhedra can be assumed all convex, and each touching pair share a polygon interface. I found polyhedron.intersection(other), but no polyhedron.union(other) or so. Any workaround I can do? Thanks in advance.Fri, 19 Feb 2021 13:55:30 +0100https://ask.sagemath.org/question/55769/union-of-touching-polyhedra/Comment by Sébastien for <p>Hi, I'm trying to do a union operation over multiple touching polyhedra into one but couldn't find how to achieve this with Sage. For example, how can I merge these two cubes and dissolve the interior face (the touching face):</p>
<pre><code># two cubes touching
cube_a = Polyhedron(vertices=[(0,0,0), (0,0,1), (0,1,0), (0,1,1), (1,0,0), (1,0,1), (1,1,0), (1,1,1)])
cube_b = Polyhedron(vertices=[(1,1/2,0), (1,1/2,1), (1,3/2,0), (1,3/2,1), (2,1/2,0), (2,1/2,1), (2,3/2,0), (2,3/2,1)])
# visualize
cube_a.plot() + cube_b.plot()
</code></pre>
<p>The polyhedra can be assumed all convex, and each touching pair share a polygon interface. I found polyhedron.intersection(other), but no polyhedron.union(other) or so. Any workaround I can do? Thanks in advance.</p>
https://ask.sagemath.org/question/55769/union-of-touching-polyhedra/?comment=55795#post-id-55795Note that you can do:
sage: cube_b = cube_a + vector((1,1/2,0))Sun, 21 Feb 2021 15:33:53 +0100https://ask.sagemath.org/question/55769/union-of-touching-polyhedra/?comment=55795#post-id-55795Answer by Max Alekseyev for <p>Hi, I'm trying to do a union operation over multiple touching polyhedra into one but couldn't find how to achieve this with Sage. For example, how can I merge these two cubes and dissolve the interior face (the touching face):</p>
<pre><code># two cubes touching
cube_a = Polyhedron(vertices=[(0,0,0), (0,0,1), (0,1,0), (0,1,1), (1,0,0), (1,0,1), (1,1,0), (1,1,1)])
cube_b = Polyhedron(vertices=[(1,1/2,0), (1,1/2,1), (1,3/2,0), (1,3/2,1), (2,1/2,0), (2,1/2,1), (2,3/2,0), (2,3/2,1)])
# visualize
cube_a.plot() + cube_b.plot()
</code></pre>
<p>The polyhedra can be assumed all convex, and each touching pair share a polygon interface. I found polyhedron.intersection(other), but no polyhedron.union(other) or so. Any workaround I can do? Thanks in advance.</p>
https://ask.sagemath.org/question/55769/union-of-touching-polyhedra/?answer=73811#post-id-73811[Polyhedral complex](https://doc.sagemath.org/html/en/reference/discrete_geometry/sage/geometry/polyhedral_complex.html) may be a way to go - e.g., try:
P = PolyhedralComplex( [cube_a, cube_b] )
P.plot()
Sun, 08 Oct 2023 00:12:22 +0200https://ask.sagemath.org/question/55769/union-of-touching-polyhedra/?answer=73811#post-id-73811Answer by Sébastien for <p>Hi, I'm trying to do a union operation over multiple touching polyhedra into one but couldn't find how to achieve this with Sage. For example, how can I merge these two cubes and dissolve the interior face (the touching face):</p>
<pre><code># two cubes touching
cube_a = Polyhedron(vertices=[(0,0,0), (0,0,1), (0,1,0), (0,1,1), (1,0,0), (1,0,1), (1,1,0), (1,1,1)])
cube_b = Polyhedron(vertices=[(1,1/2,0), (1,1/2,1), (1,3/2,0), (1,3/2,1), (2,1/2,0), (2,1/2,1), (2,3/2,0), (2,3/2,1)])
# visualize
cube_a.plot() + cube_b.plot()
</code></pre>
<p>The polyhedra can be assumed all convex, and each touching pair share a polygon interface. I found polyhedron.intersection(other), but no polyhedron.union(other) or so. Any workaround I can do? Thanks in advance.</p>
https://ask.sagemath.org/question/55769/union-of-touching-polyhedra/?answer=55779#post-id-55779Let me first define your polyhedron over the same base ring:
sage: cube_a = Polyhedron(vertices=[(0,0,0), (0,0,1), (0,1,0), (0,1,1), (1,0,0), (1,0,1), (1,1,0), (1,1,1)], base_ring=QQ)
sage: cube_b = Polyhedron(vertices=[(1,1/2,0), (1,1/2,1), (1,3/2,0), (1,3/2,1), (2,1/2,0), (2,1/2,1), (2,3/2,0), (2,3/2,1)], base_ring=QQ)
sage: cube_a
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
sage: cube_b
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
You may define this function which returns the convex hull of a list of polyhedron:
def convex_hull(list_of_polyhedron):
V = sum((p.vertices() for p in list_of_polyhedron), tuple())
return Polyhedron(V)
In your case, you obtain:
sage: convex_hull([cube_a, cube_b])
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 12 vertices
If the union is convex, the convex hull is the union. In your case, the convex hull does not seem to be equal to the union of the two cubes. Comparing their volume, we obtain:
sage: cube_a.volume()
1
sage: cube_b.volume()
1
sage: convex_hull([cube_a, cube_b]).volume()
5/2
Recently, I needed to check [whether the union of a list of polyhedron is convex](https://www.labri.fr/perso/slabbe/docs/0.6.2/polyhedron_partition.html#slabbe.polyhedron_partition.is_union_convex) before creating their union using convex hull. I wrote that in my package which can be installed with `sage -pip install slabbe`. In your case, it returns False, so the convex hull is not equal to the union of the two polyhedron:
sage: from slabbe.polyhedron_partition import is_union_convex
sage: is_union_convex([cube_a, cube_b])
False
Sat, 20 Feb 2021 09:30:06 +0100https://ask.sagemath.org/question/55769/union-of-touching-polyhedra/?answer=55779#post-id-55779Comment by zhaiyu for <p>Let me first define your polyhedron over the same base ring:</p>
<pre><code>sage: cube_a = Polyhedron(vertices=[(0,0,0), (0,0,1), (0,1,0), (0,1,1), (1,0,0), (1,0,1), (1,1,0), (1,1,1)], base_ring=QQ)
sage: cube_b = Polyhedron(vertices=[(1,1/2,0), (1,1/2,1), (1,3/2,0), (1,3/2,1), (2,1/2,0), (2,1/2,1), (2,3/2,0), (2,3/2,1)], base_ring=QQ)
sage: cube_a
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
sage: cube_b
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
</code></pre>
<p>You may define this function which returns the convex hull of a list of polyhedron:</p>
<pre><code>def convex_hull(list_of_polyhedron):
V = sum((p.vertices() for p in list_of_polyhedron), tuple())
return Polyhedron(V)
</code></pre>
<p>In your case, you obtain:</p>
<pre><code>sage: convex_hull([cube_a, cube_b])
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 12 vertices
</code></pre>
<p>If the union is convex, the convex hull is the union. In your case, the convex hull does not seem to be equal to the union of the two cubes. Comparing their volume, we obtain:</p>
<pre><code>sage: cube_a.volume()
1
sage: cube_b.volume()
1
sage: convex_hull([cube_a, cube_b]).volume()
5/2
</code></pre>
<p>Recently, I needed to check <a href="https://www.labri.fr/perso/slabbe/docs/0.6.2/polyhedron_partition.html#slabbe.polyhedron_partition.is_union_convex">whether the union of a list of polyhedron is convex</a> before creating their union using convex hull. I wrote that in my package which can be installed with <code>sage -pip install slabbe</code>. In your case, it returns False, so the convex hull is not equal to the union of the two polyhedron:</p>
<pre><code>sage: from slabbe.polyhedron_partition import is_union_convex
sage: is_union_convex([cube_a, cube_b])
False
</code></pre>
https://ask.sagemath.org/question/55769/union-of-touching-polyhedra/?comment=55803#post-id-55803That I know. I just found out the union thing can be done with [3D Boolean Operations on Nef Polyhedra](https://doc.cgal.org/latest/Nef_3/index.html). While Sage doesn't have it (seems the Nef representation does exist for lattice polytope though), CGAL has it implemented. Thanks again.Sun, 21 Feb 2021 23:12:23 +0100https://ask.sagemath.org/question/55769/union-of-touching-polyhedra/?comment=55803#post-id-55803Comment by Sébastien for <p>Let me first define your polyhedron over the same base ring:</p>
<pre><code>sage: cube_a = Polyhedron(vertices=[(0,0,0), (0,0,1), (0,1,0), (0,1,1), (1,0,0), (1,0,1), (1,1,0), (1,1,1)], base_ring=QQ)
sage: cube_b = Polyhedron(vertices=[(1,1/2,0), (1,1/2,1), (1,3/2,0), (1,3/2,1), (2,1/2,0), (2,1/2,1), (2,3/2,0), (2,3/2,1)], base_ring=QQ)
sage: cube_a
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
sage: cube_b
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
</code></pre>
<p>You may define this function which returns the convex hull of a list of polyhedron:</p>
<pre><code>def convex_hull(list_of_polyhedron):
V = sum((p.vertices() for p in list_of_polyhedron), tuple())
return Polyhedron(V)
</code></pre>
<p>In your case, you obtain:</p>
<pre><code>sage: convex_hull([cube_a, cube_b])
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 12 vertices
</code></pre>
<p>If the union is convex, the convex hull is the union. In your case, the convex hull does not seem to be equal to the union of the two cubes. Comparing their volume, we obtain:</p>
<pre><code>sage: cube_a.volume()
1
sage: cube_b.volume()
1
sage: convex_hull([cube_a, cube_b]).volume()
5/2
</code></pre>
<p>Recently, I needed to check <a href="https://www.labri.fr/perso/slabbe/docs/0.6.2/polyhedron_partition.html#slabbe.polyhedron_partition.is_union_convex">whether the union of a list of polyhedron is convex</a> before creating their union using convex hull. I wrote that in my package which can be installed with <code>sage -pip install slabbe</code>. In your case, it returns False, so the convex hull is not equal to the union of the two polyhedron:</p>
<pre><code>sage: from slabbe.polyhedron_partition import is_union_convex
sage: is_union_convex([cube_a, cube_b])
False
</code></pre>
https://ask.sagemath.org/question/55769/union-of-touching-polyhedra/?comment=56363#post-id-56363In fact, you may define non convex polyhedron in sage, see: https://ask.sagemath.org/question/50929/Wed, 24 Mar 2021 21:55:07 +0100https://ask.sagemath.org/question/55769/union-of-touching-polyhedra/?comment=56363#post-id-56363Comment by zhaiyu for <p>Let me first define your polyhedron over the same base ring:</p>
<pre><code>sage: cube_a = Polyhedron(vertices=[(0,0,0), (0,0,1), (0,1,0), (0,1,1), (1,0,0), (1,0,1), (1,1,0), (1,1,1)], base_ring=QQ)
sage: cube_b = Polyhedron(vertices=[(1,1/2,0), (1,1/2,1), (1,3/2,0), (1,3/2,1), (2,1/2,0), (2,1/2,1), (2,3/2,0), (2,3/2,1)], base_ring=QQ)
sage: cube_a
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
sage: cube_b
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
</code></pre>
<p>You may define this function which returns the convex hull of a list of polyhedron:</p>
<pre><code>def convex_hull(list_of_polyhedron):
V = sum((p.vertices() for p in list_of_polyhedron), tuple())
return Polyhedron(V)
</code></pre>
<p>In your case, you obtain:</p>
<pre><code>sage: convex_hull([cube_a, cube_b])
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 12 vertices
</code></pre>
<p>If the union is convex, the convex hull is the union. In your case, the convex hull does not seem to be equal to the union of the two cubes. Comparing their volume, we obtain:</p>
<pre><code>sage: cube_a.volume()
1
sage: cube_b.volume()
1
sage: convex_hull([cube_a, cube_b]).volume()
5/2
</code></pre>
<p>Recently, I needed to check <a href="https://www.labri.fr/perso/slabbe/docs/0.6.2/polyhedron_partition.html#slabbe.polyhedron_partition.is_union_convex">whether the union of a list of polyhedron is convex</a> before creating their union using convex hull. I wrote that in my package which can be installed with <code>sage -pip install slabbe</code>. In your case, it returns False, so the convex hull is not equal to the union of the two polyhedron:</p>
<pre><code>sage: from slabbe.polyhedron_partition import is_union_convex
sage: is_union_convex([cube_a, cube_b])
False
</code></pre>
https://ask.sagemath.org/question/55769/union-of-touching-polyhedra/?comment=55782#post-id-55782Thanks for the answer! The union in the example is intentionally not convex. What I'd like to have in the end is the outer surface of the union (doesn't have to be Sage's polyhedron which as I understand should be convex; it can be polygons3d or just the boundary representation of the mesh). I checked your slabbe package (PolyhedronPartition seems close to my needs) but couldn't find the desired function.Sat, 20 Feb 2021 11:41:19 +0100https://ask.sagemath.org/question/55769/union-of-touching-polyhedra/?comment=55782#post-id-55782Comment by Sébastien for <p>Let me first define your polyhedron over the same base ring:</p>
<pre><code>sage: cube_a = Polyhedron(vertices=[(0,0,0), (0,0,1), (0,1,0), (0,1,1), (1,0,0), (1,0,1), (1,1,0), (1,1,1)], base_ring=QQ)
sage: cube_b = Polyhedron(vertices=[(1,1/2,0), (1,1/2,1), (1,3/2,0), (1,3/2,1), (2,1/2,0), (2,1/2,1), (2,3/2,0), (2,3/2,1)], base_ring=QQ)
sage: cube_a
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
sage: cube_b
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
</code></pre>
<p>You may define this function which returns the convex hull of a list of polyhedron:</p>
<pre><code>def convex_hull(list_of_polyhedron):
V = sum((p.vertices() for p in list_of_polyhedron), tuple())
return Polyhedron(V)
</code></pre>
<p>In your case, you obtain:</p>
<pre><code>sage: convex_hull([cube_a, cube_b])
A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 12 vertices
</code></pre>
<p>If the union is convex, the convex hull is the union. In your case, the convex hull does not seem to be equal to the union of the two cubes. Comparing their volume, we obtain:</p>
<pre><code>sage: cube_a.volume()
1
sage: cube_b.volume()
1
sage: convex_hull([cube_a, cube_b]).volume()
5/2
</code></pre>
<p>Recently, I needed to check <a href="https://www.labri.fr/perso/slabbe/docs/0.6.2/polyhedron_partition.html#slabbe.polyhedron_partition.is_union_convex">whether the union of a list of polyhedron is convex</a> before creating their union using convex hull. I wrote that in my package which can be installed with <code>sage -pip install slabbe</code>. In your case, it returns False, so the convex hull is not equal to the union of the two polyhedron:</p>
<pre><code>sage: from slabbe.polyhedron_partition import is_union_convex
sage: is_union_convex([cube_a, cube_b])
False
</code></pre>
https://ask.sagemath.org/question/55769/union-of-touching-polyhedra/?comment=55796#post-id-55796Then, maybe you want to compute the intersection of their faces:
sage: cube_a.faces(face_dimension=2)
(A 2-dimensional face of a Polyhedron in QQ^3 defined as the convex hull of 4 vertices,
...
A 2-dimensional face of a Polyhedron in QQ^3 defined as the convex hull of 4 vertices)
Unfortunately, those faces do not have a `intersection` method. So you will need to use their H-representation to compute their intersection with another face. It seems doable in few lines.Sun, 21 Feb 2021 15:41:55 +0100https://ask.sagemath.org/question/55769/union-of-touching-polyhedra/?comment=55796#post-id-55796