Wolfram Research

Function Repository Resource:

SimplexBoundary

Source Notebook

Find the topological boundary of a simplex or simplicial complex

Contributed by: Richard Hennigan (Wolfram Research)

ResourceFunction["SimplexBoundary"][simplex]

finds the topological boundary of simplex.

ResourceFunction["SimplexBoundary"][{simplex1,simplex2,}]

finds the topological boundary of the simplicial complex containing simplex1,simplex2,.

ResourceFunction["SimplexBoundary"][mesh]

finds the topological boundary of the MeshRegion mesh.

ResourceFunction["SimplexBoundary"][complex,k]

finds the topological boundary of the k-skeleton of complex.

Details and Options

A simplex can be considered any of the following:
Point[v] point
Line[{v1,v2}] line segment
Triangle[{v1,v2,v3}] or Polygon[{v1,v2,v3}] filled triangle
Tetrahedron[{v1,v2,v3,v4}] filled tetrahedron
Simplex[{v1,v2,,vn}] an n-1 dimensional simplex
A simplicial complex is either a list of simplices or a MeshRegion where all cells are valid simplices.
The boundary preserves orientations so that it can be used for simplicial homology computations.

Examples

Basic Examples

Retrieve the ResourceFunction:

In[1]:=
ResourceFunction["SimplexBoundary"]
Out[1]=

Get the boundary of a Simplex:

In[2]:=
ResourceFunction["SimplexBoundary"][Simplex[{1, 2, 3}]]
Out[2]=

Get the boundary of a simplicial complex, represented as a list of simplices:

In[3]:=
ResourceFunction[
 "SimplexBoundary"][{Simplex[{1, 2, 3}], Simplex[{1, 3, 4}]}]
Out[3]=

Get the boundary of a MeshRegion:

In[4]:=
mesh = MeshRegion[{{0, 0}, {1, 0}, {0, 1}, {1, 1}, {2, 1}, {2, 0}}, Polygon[{{1, 2, 3}, {4, 5, 6}}]]
Out[4]=
In[5]:=
ResourceFunction["SimplexBoundary"][mesh]
Out[5]=

Scope

By default, the boundary will be computed from simplices that match the dimension of the simplicial complex:

In[6]:=
ResourceFunction[
 "SimplexBoundary"][{Point[1], Line[{2, 3}], Triangle[{4, 5, 6}]}]
Out[6]=

A different dimension k can be specified, which will find the boundary of the k-skeleton of the complex:

In[7]:=
ResourceFunction[
 "SimplexBoundary"][{Point[1], Line[{2, 3}], Triangle[{4, 5, 6}]}, 1]
Out[7]=

Generalizations and Extensions

Some other primitives can represent a simplex as well:

In[8]:=
ResourceFunction["SimplexBoundary"][
 Triangle[{{0, 0}, {1, 0}, {0, 1}}]]
Out[8]=
In[9]:=
Graphics[%]
Out[9]=

Applications

Find holes in a 3D model:

In[10]:=
mesh = ResourceData["Stanford Bunny", "MeshRegion"]
Out[10]=
In[11]:=
boundary = ResourceFunction["SimplexBoundary"][mesh]
Out[11]=

Highlight the boundary edges:

In[12]:=
Show[HighlightMesh[mesh, Style[boundary, Red]], ViewPoint -> {-2.25, -0.5, -2.5}, ViewVertical -> {-1, 0, 0}]
Out[12]=

Properties and Relations

Orientation is preserved:

In[13]:=
pts = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
boundary = ResourceFunction["SimplexBoundary"][Tetrahedron[{1, 2, 3, 4}]];
insideOutBoundary = ResourceFunction["SimplexBoundary"][Tetrahedron[{2, 1, 3, 4}]];
{Graphics3D[{FaceForm[Red, Blue], GraphicsComplex[pts, boundary]}], Graphics3D[{FaceForm[Red, Blue], GraphicsComplex[pts, insideOutBoundary]}]}
Out[13]=
In[14]:=
pts = {{0, 0}, {1, 0}, {0, 1}};
boundary = ResourceFunction["SimplexBoundary"][Triangle[{1, 2, 3}]];
insideOutBoundary = ResourceFunction["SimplexBoundary"][Triangle[{2, 1, 3}]];
{Graphics[GraphicsComplex[pts, Arrow @@@ boundary]], Graphics[GraphicsComplex[pts, Arrow @@@ insideOutBoundary]]}
Out[14]=

The boundary of a boundary is always empty:

In[15]:=
NestList[ResourceFunction["SimplexBoundary"],
 MeshRegion[{{0, 0}, {1, 0}, {0, 1}, {1, 1}, {2, 1}, {2, 0}}, Polygon[{{1, 2, 3}, {4, 5, 6}}]], 2]
Out[15]=
In[16]:=
Graphics /@ NestList[ResourceFunction["SimplexBoundary"], Triangle[], 2]
Out[16]=
In[17]:=
Graphics /@ NestList[ResourceFunction[
  "SimplexBoundary"], {Simplex[{{0, 0}, {1, 0}, {0, 1}}], Simplex[{{1, 1}, {1, 0}, {0, 1}}]}, 2]
Out[17]=

A graph can be considered a one-dimensional simplicial complex:

In[18]:=
g = \!\(\*
GraphicsBox[
NamespaceBox["NetworkGraphics",
DynamicModuleBox[{Typeset`graph = HoldComplete[
Graph[{2, 4, 3, 9, 16, 5, 25, 6, 36, 7, 49, 8, 64, 10, 26, 11, 47, 12,
          70, 13, 21, 14, 48, 15, 34, 17, 67, 18, 28, 19, 65, 20, 30, 71, 22, 40, 23, 24, 58, 33, 27, 63, 44, 29, 31, 73, 32, 62, 53, 46, 35, 41, 38, 39, 42, 43, 45, 50, 51, 52, 54, 55, 56, 57, 59, 60, 61, 66, 68, 69, 72, 1, 0, 74, 75, 76, 77, 78, 79,
          80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100}, {
         Null, {{1, 2}, {3, 4}, {2, 5}, {6, 7}, {8, 9}, {10, 11}, {12,
           13}, {10, 4}, {14, 15}, {16, 17}, {18, 19}, {20, 21}, {22, 23}, {3, 24}, {5, 25}, {26, 27}, {28, 29}, {30, 31}, {32, 33}, {21, 34}, {35, 36}, {16, 37}, {38, 39}, {7, 40}, {41, 42}, {29, 43}, {41, 44}, {18, 33}, {45, 46}, {47, 48}, {40, 49}, {25, 50}, {51, 52}, {9, 53}, {54, 52}, {36, 50}, {52, 49}, {55, 48}, {56, 46}, {18, 43}, {41, 57}, {43, 50}, {17, 42}, {14, 23}, {40, 11}, {58, 39}, {16, 59}, {36, 60}, {49, 34}, {33, 61}, {62, 31}, {29, 63}, {64, 27}, {25, 39}, {3, 65}, {23, 66}, {21, 67}, {48, 19}, {15, 13}, {10, 31}, {13, 68}, {11, 27}, {9, 69}, {7, 70}, {5, 19}, {4, 34}, {2, 71}, {72, 46}, {73, 74}, {72, 75}, {2, 76}, {4, 77}, {5, 78}, {7, 79}, {9, 80}, {11, 81}, {13, 82}, {10, 83}, {15, 84}, {17, 85}, {19, 86}, {21, 87}, {23, 88}, {3, 89}, {25, 90}, {27, 91}, {29, 92}, {31, 93}, {33, 94}, {34, 95}, {36, 96}, {16, 97}, {39, 98}, {40, 99}, {14, 100}}}]]}, 
TagBox[GraphicsGroupBox[GraphicsComplexBox[CompressedData["
1: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
NPlyVMhJIVTt8jDt7aLi/wB49+93
"], {
{Hue[0.6, 0.7, 0.5], Opacity[0.7], 
{Arrowheads[0.], ArrowBox[{1, 2}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{2, 5}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{2, 71}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{2, 76}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{3, 4}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{3, 24}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{3, 65}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{3, 89}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{4, 10}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{4, 34}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{4, 77}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{5, 19}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{5, 25}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{5, 78}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{6, 7}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{7, 40}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{7, 70}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{7, 79}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{8, 9}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{9, 53}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{9, 69}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{9, 80}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{10, 11}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{10, 31}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{10, 83}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{11, 27}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{11, 40}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{11, 81}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{12, 13}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{13, 15}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{13, 68}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{13, 82}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{14, 15}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{14, 23}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{14, 100}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{15, 84}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{16, 17}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{16, 37}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{16, 59}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{16, 97}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{17, 42}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{17, 85}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{18, 19}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{18, 33}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{18, 43}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{19, 48}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{19, 86}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{20, 21}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{21, 34}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{21, 67}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{21, 87}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{22, 23}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{23, 66}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{23, 88}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{25, 39}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{25, 50}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{25, 90}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{26, 27}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{27, 64}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{27, 91}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{28, 29}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{29, 43}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{29, 63}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{29, 92}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{30, 31}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{31, 62}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{31, 93}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{32, 33}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{33, 61}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{33, 94}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{34, 49}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{34, 95}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{35, 36}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{36, 50}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{36, 60}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{36, 96}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{38, 39}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{39, 58}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{39, 98}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{40, 49}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{40, 99}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{41, 42}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{41, 44}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{41, 57}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{43, 50}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{45, 46}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{46, 56}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{46, 72}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{47, 48}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{48, 55}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{49, 52}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{51, 52}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{52, 54}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{72, 75}, 0.07916234730017717]}, 
{Arrowheads[0.], ArrowBox[{73, 74}, 0.07916234730017717]}}, 
{Hue[0.6, 0.2, 0.8], EdgeForm[{GrayLevel[0], Opacity[0.7]}], DiskBox[1, 0.07916234730017717], DiskBox[2, 0.07916234730017717], DiskBox[3, 0.07916234730017717], DiskBox[4, 0.07916234730017717], DiskBox[5, 0.07916234730017717], DiskBox[6, 0.07916234730017717], DiskBox[7, 0.07916234730017717], DiskBox[8, 0.07916234730017717], DiskBox[9, 0.07916234730017717], DiskBox[10, 0.07916234730017717], DiskBox[11, 0.07916234730017717], DiskBox[12, 0.07916234730017717], DiskBox[13, 0.07916234730017717], DiskBox[14, 0.07916234730017717], DiskBox[15, 0.07916234730017717], DiskBox[16, 0.07916234730017717], DiskBox[17, 0.07916234730017717], DiskBox[18, 0.07916234730017717], DiskBox[19, 0.07916234730017717], DiskBox[20, 0.07916234730017717], DiskBox[21, 0.07916234730017717], DiskBox[22, 0.07916234730017717], DiskBox[23, 0.07916234730017717], DiskBox[24, 0.07916234730017717], DiskBox[25, 0.07916234730017717], DiskBox[26, 0.07916234730017717], DiskBox[27, 0.07916234730017717], DiskBox[28, 0.07916234730017717], DiskBox[29, 0.07916234730017717], DiskBox[30, 0.07916234730017717], DiskBox[31, 0.07916234730017717], DiskBox[32, 0.07916234730017717], DiskBox[33, 0.07916234730017717], DiskBox[34, 0.07916234730017717], DiskBox[35, 0.07916234730017717], DiskBox[36, 0.07916234730017717], DiskBox[37, 0.07916234730017717], DiskBox[38, 0.07916234730017717], DiskBox[39, 0.07916234730017717], DiskBox[40, 0.07916234730017717], DiskBox[41, 0.07916234730017717], DiskBox[42, 0.07916234730017717], DiskBox[43, 0.07916234730017717], DiskBox[44, 0.07916234730017717], DiskBox[45, 0.07916234730017717], DiskBox[46, 0.07916234730017717], DiskBox[47, 0.07916234730017717], DiskBox[48, 0.07916234730017717], DiskBox[49, 0.07916234730017717], DiskBox[50, 0.07916234730017717], DiskBox[51, 0.07916234730017717], DiskBox[52, 0.07916234730017717], DiskBox[53, 0.07916234730017717], DiskBox[54, 0.07916234730017717], DiskBox[55, 0.07916234730017717], DiskBox[56, 0.07916234730017717], DiskBox[57, 0.07916234730017717], DiskBox[58, 0.07916234730017717], DiskBox[59, 0.07916234730017717], DiskBox[60, 0.07916234730017717], DiskBox[61, 0.07916234730017717], DiskBox[62, 0.07916234730017717], DiskBox[63, 0.07916234730017717], DiskBox[64, 0.07916234730017717], DiskBox[65, 0.07916234730017717], DiskBox[66, 0.07916234730017717], DiskBox[67, 0.07916234730017717], DiskBox[68, 0.07916234730017717], DiskBox[69, 0.07916234730017717], DiskBox[70, 0.07916234730017717], DiskBox[71, 0.07916234730017717], DiskBox[72, 0.07916234730017717], DiskBox[73, 0.07916234730017717], DiskBox[74, 0.07916234730017717], DiskBox[75, 0.07916234730017717], DiskBox[76, 0.07916234730017717], DiskBox[77, 0.07916234730017717], DiskBox[78, 0.07916234730017717], DiskBox[79, 0.07916234730017717], DiskBox[80, 0.07916234730017717], DiskBox[81, 0.07916234730017717], DiskBox[82, 0.07916234730017717], DiskBox[83, 0.07916234730017717], DiskBox[84, 0.07916234730017717], DiskBox[85, 0.07916234730017717], DiskBox[86, 0.07916234730017717], DiskBox[87, 0.07916234730017717], DiskBox[88, 0.07916234730017717], DiskBox[89, 0.07916234730017717], DiskBox[90, 0.07916234730017717], DiskBox[91, 0.07916234730017717], DiskBox[92, 0.07916234730017717], DiskBox[93, 0.07916234730017717], DiskBox[94, 0.07916234730017717], DiskBox[95, 0.07916234730017717], DiskBox[96, 0.07916234730017717], DiskBox[97, 0.07916234730017717], DiskBox[98, 0.07916234730017717], DiskBox[99, 0.07916234730017717], DiskBox[100, 0.07916234730017717]}}]],
MouseAppearanceTag["NetworkGraphics"]],
AllowKernelInitialization->False]],
DefaultBaseStyle->{
      "NetworkGraphics", FrontEnd`GraphicsHighlightColor -> Hue[0.8, 1., 0.6]},
FormatType->TraditionalForm,
FrameTicks->None]\);
boundary = ResourceFunction["SimplexBoundary"][
   EdgeList[g] /. UndirectedEdge[a_, b_] :> Line[{a, b}]] /. Simplex[{n_}] :> n
Out[18]=
In[19]:=
HighlightGraph[g, boundary]
Out[19]=

The boundary can give you information about degree of vertices:

In[20]:=
Sort[boundary] === Sort[Keys@
   Select[AssociationThread[VertexList[g], VertexDegree[g]], # == 1 &]]
Out[20]=

Possible Issues

Not all graphics primitives are valid simplices:

In[21]:=
arc = Circle[{0, 0}, 1, {Pi/6, 3 Pi/4}];
Graphics[arc]
Out[21]=
Out[21]=

They can often be converted to simplicial complexes using DiscretizeGraphics that are reasonable approximations:

In[22]:=
d = DiscretizeGraphics[arc]
Out[22]=
In[23]:=
Graphics[{arc, Style[MeshPrimitives[ResourceFunction["SimplexBoundary"][d], 0], Red, PointSize[Large]]}]
Out[23]=

Valid n-dimensional simplices must have n+1 vertices:

Out[23]=
In[24]:=
ResourceFunction["SimplexBoundary"][Polygon[{1, 2, 3}]]
Out[24]=

Mesh regions are not necessarily composed of simplices:

In[25]:=
mesh = DiscretizeGraphics[Rectangle[]]
Out[25]=
Out[25]=

TriangulateMesh can often be used to create a valid simplicial complex:

In[26]:=
ResourceFunction["SimplexBoundary"][
 TriangulateMesh[mesh, MaxCellMeasure -> Infinity]]
Out[26]=

Vertices must be unique:

Out[26]=

If orientations are not consistent within a simplicial complex, the boundary will not have consistent orientations, either:

In[27]:=
s = {Simplex[{{0, 0, 0}, {1, 0, 0}, {0, 1, 0}}], Simplex[{{1, 1, 0}, {1, 0, 0}, {0, 1, 0}}]};
Graphics3D[{FaceForm[Red, Blue], s}, BoxRatios -> {1, 1, .1}, Boxed -> False]
Out[27]=
In[28]:=
Graphics3D[Arrow @@@ ResourceFunction["SimplexBoundary"][s], BoxRatios -> {1, 1, .1}, Boxed -> False]
Out[28]=

Interactive Examples

One can visualize 4D shapes by rotating and projecting the boundary into 3D. Here is an example using a hexadecachoron:

In[29]:=
rotationFunction = Block[{\[Theta]1, \[Theta]2, \[Theta]3, \[Theta]4, \[Theta]5, \
\[Theta]6}, With[{rotateExpr = Simplify[
       N[(Composition @@ RotationTransform @@@ Transpose[{{\[Theta]1, \[Theta]2, \[Theta]3, \[Theta]4, \
\[Theta]5, \[Theta]6}, Subsets[IdentityMatrix[4], {2}]}])[{x, y, z, w}]], Reals]},
    Compile[{{r, _Real, 1}, {v, _Real, 1}},
     Block[{\[Theta]1, \[Theta]2, \[Theta]3, \[Theta]4, \[Theta]5, \
\[Theta]6, x, y, z, w},
      {\[Theta]1, \[Theta]2, \[Theta]3, \[Theta]4, \[Theta]5, \
\[Theta]6} = r;
      {x, y, z, w} = v;
      rotateExpr
      ],
     CompilationOptions -> {"ExpressionOptimization" -> True},
     RuntimeOptions -> "Speed",
     RuntimeAttributes -> {Listable},
     Parallelization -> True
     ]
    ]];

vertices = Flatten[Table[
    Chop[rotationFunction[r, Prepend[IdentityMatrix[4], {0, 0, 0, 0}]]], {r, Pi*IdentityMatrix[6]}], 1];
hexadecachoron = Table[Simplex[{1, 2, 3, 4, 5} + 5 n], {n, 0, 5}]
Out[29]=
In[30]:=
Manipulate[
 Graphics3D[{EdgeForm[Thick], Opacity[.25], GraphicsComplex[
    rotationFunction[{\[Theta]1, \[Theta]2, \[Theta]3, \[Theta]4, \
\[Theta]5, \[Theta]6}, vertices][[All, ;; 3]], ResourceFunction["SimplexBoundary"][hexadecachoron]]}, PlotRange -> 1, ViewAngle -> Pi/10, Boxed -> False],
 {{\[Theta]1, 1}, -2 Pi, 2 Pi},
 {{\[Theta]2, 1}, -2 Pi, 2 Pi},
 {{\[Theta]3, 1}, -2 Pi, 2 Pi},
 {{\[Theta]4, 1}, -2 Pi, 2 Pi},
 {{\[Theta]5, 1}, -2 Pi, 2 Pi},
 {{\[Theta]6, 1}, -2 Pi, 2 Pi}
 ]
Out[30]=

Neat Examples

The boundary of an annulus is two circles, while the boundary of a Moebius strip is a single circle:

In[31]:=
{ResourceFunction["SimplexBoundary"][\!\(\*
GraphicsBox[
TagBox[
DynamicModuleBox[{Typeset`mesh = {
       MeshRegion, {Method -> {"PropagateMarkers" -> False}}}}, 
TagBox[GraphicsComplexBox[CompressedData["
1:eJxVVH1M1HUYP0loWtZc+dJgAhnnelsM+qfJekJBDTVfpkbFQbUoXxCSlQ0J
KePo4MzE1dqIGLqFAVnKiyy6fFBepvHS8XLOBkRB56Lj/YB1cN2V9/08t/3Y
2Hf3/T3f5/l8Ps/necJfz9idGqDT6b78///O2bY+983SstvUqU5O+C3w3abF
I9QzZh4qcw5z/MvLXjKsdlBhR/jD+4P+oCNJbRWW3lG6WnVke2NzH6U88MbJ
nPYJei3jyejaCgsdGEkMLImaoBPxAcOns9vJXXHg54S1Ns4ngzXh6XH6QN2z
xG1FvS5Vj1KRR/LmIY/E3530YLS+vChG5/ub9OOKA85rwCU4u5FX6jSq7yzf
jT5cHgqovIPTzm/77t3U4otzcDt06YBO0IclL3ixzvfeRur9KDcBB3jxNtQH
D84HL/DkRMWbwYsVz7Mx0J8LFE/BzQweyMtW1JH8x6Gz6LTE2jIeZfrCYkYe
6MXNyCO404FDcC0tLN32TFalRXDNq376eV8Bz0y8L9D2l9/X9o+N8IHS28b7
0Vcz3gEH9O8TXiQ8xZfSB+mLnPnop8eH0w4fuOFXB/T2wq+Cywu/9gsvvLeR
4q17Tul33qLqzJGcygdO+MvlP7twr/q3AJ9OkVerH37b/bjzgENwXQNu4SF5
4pBX+WKKpQ7qwhcu+N3B8t6geLPooOaxn6We+E54p0IniTdo/UHiS9kTat7t
LHzEZ2bNnC7g9xTmxY15cWC+XCy6qvmbY9FbfHkQewJ1eAF1wQP+7xeeiG+X
fjYqnpdiJD5f038P5tnu9/kC9hh0xPw5/PkToavsUdkbncAvPHrQH+GZru0H
5sffD16EOcHcSJ9Z+o4+Y06coiuLzs3AKTrv0e5X5Lcjvwff/f3G/Pr9iH3Q
YBEdTeir7CkT+io4gYsE5xX0ORN45rX+543w0Un4aiN8fRK8oBuJjm3whegs
vszU+NSL3+3YN17sm34uf/bc2ufDnBxWv7n20Ufs/OpVT153cQ2XLLN+nt81
y7FLJzI+SRhhfcErpz7qnvLfJ6k4+vGgudywdZJXrdi0xxg6RhsWPxVyYUsH
Hzrc2rvFPEt2Z8jeyz/8TvpvNwxmR84w4ilExfPHzevf+d47Q72bvfG2qFv8
N+IjVDz9hHjJb0K8VcXTd03VyQM9U9zVuav0m4IB3nfsbGOoZ5zLbgQNGaod
7E4rdtftuETelMuta+KcvM5xPLmm7wavPDX26eogJ8c+NHh+SdUQ70qsiT0x
PMkSpzvse+ePi1DvKPfMryHHIqd50+DOoyuD/6R7M40rkupHuDf4Qtr11lE6
FFq3KMA6yCnG3OkXo50UiDzISxezjDv0yTYqiRz4padwmknVp92of4/KRzdV
PkY9SlD1eLi4tmqWZ6jwqGvVXV9Xc602H4EPgQ/NN0waT2dN0Gc5MV9F7L1N
92nzE/hROPhBT7qp9KT0nOVh6yr/4bCGEsf2tH7W45R7OR9T99Q6e+uJvtox
Tl4+ty9wYoZMOz9M/zeonkznshPLylyUnB1eVBfVRXMFa94KfcHFLSqeUlQ8
X3xcX3P/e3MUXOQo8fb+Rdfx3YB8/wEFNBJf
"], 
{Hue[0.6, 0.3, 0.95], EdgeForm[Hue[0.6, 0.3, 0.75]], 
TagBox[PolygonBox[CompressedData["
1:eJwNw4V2qgAAANBNF67LpesO152uu7vDdTrEQgURKQUsQOp/3ne93XNuk9V2
aNWlpaX9+6v/W3sEm2ph5Obs7BxEzkAwaIZ54JjfGRvxwUf18wsuEwzcIEAN
Vg3wx7v8yYNwdyFcXtgFNND8+C6HtqvQ9quSX8gqPwWbGu/pDsQE1JmQG+B6
b98RQO3H18ApYkab2xvNwTrktLAgSpRVCnZ0HXeKe44Tx34y4WchG7YdWs6n
KtbwrU3n9KS3qjy0jdUc7IkH4iEuhnrjRbkcNZTMcG6ux33aljO1voHHkurc
Vioa17CQwzslyQH7VRA1lhG40VmcTZ7fgk4j8en5wuqryRRhRkCicoVctaRm
51h/oiGRaVimvr880rxr1bUgbhySBheZbUj61VXStWbE+/rVaFF8d4cP3Lc0
B1rc8ntnN0PfB+i2Vrq1w/ooK5FwJwPR4ba28DNeXlGPwZH0np5wRMd8eBgd
l5vX8xyW6YDy+l2Oh16Vl4guvQQqZUohzRv9LGWY7g/G89kJdUFsV/CqiR3w
96n+hh+W/elSfTHbMGuDfpcWpWltxqN8k8TKxZMdvBO8k1NcYVQfy0lZZntj
cccJz0W9I6Oa8vZSFC3g8ibe39yL81J+LjVRyElTSw4ec1ESGhQol2Gwzw9j
fFKf4dFFwrSbXClOZGXGY76BQT87PPAk27MSQ4on0sAmlLB7XO0f0XzatHdD
xEOiwytx6pjPkiK10RmKk3JivWPqOJFyym46OZR4uBRAIfimuO/AW30y9h+L
MeVS
"]],
Annotation[#, "Geometry"]& ]}],
MouseAppearanceTag["LinkHand"]],
AllowKernelInitialization->False],
"MeshGraphics",
AutoDelete->True,
Editable->False,
Selectable->False],
DefaultBaseStyle->{
      "MeshGraphics", FrontEnd`GraphicsHighlightColor -> Hue[0.1, 1, 0.7]},
ImageSize->{Automatic, 99.8576}]\)], ResourceFunction["SimplexBoundary"][\!\(\*
Graphics3DBox[
TagBox[
DynamicModuleBox[{Typeset`mesh = {MeshRegion, {}}}, 
TagBox[GraphicsComplex3DBox[CompressedData["
1:eJx1WGlsFVUYnbavLYjs+gOS6qAGg2iIQDEp4b0RsBBCWBMFpHYgUgRR5Aea
aDQTEAJCoYUgAakOCSkmQGRTK0LnIkiISCwgWFnK0EKBlqWlWLALz7lnZsK5
E3lJM7lnvvnuty/tM3P+pFmpmqad9P7SNP83oK2T4T2Mgz/uT3hPsWmOJZ9G
1q2uEjfzCyrk2ew2x8bTbMqUuJa/8WhCe/izkkcyJK73Nm4xbv9R00XiYsqg
BvB/7S0hn/aYpZ1Bn3ntHujdj8DP3DaoGfePHJVuMP/OXTR5tpo/eUw+7drZ
FyWd9fm5+/iutOfjkDdt4SWcC7/B91bRqbssj/nxVuhrvtQ3ie+rhkI/d1Ju
Kujfz0oyvbt6YkfIMfEK3hs/vfCnfK8PLIa+xtWzvpx5sUroV/IM5BQjD6ew
/NqLC9PA/+WCDvLp7j98DvfsWQV7unVTq/lerbgM9nf16S741hbsxL39P2yF
3M9+l8b8jcq1sK/RtCSDcXP4uEbYY9HzsLfxw7M1OC+42e5IPmsOpSp8eu5O
StzsXgY+IiX/BuibxqcK+f5uvxj0ODv8Juz2VUmZpHf/astU7v1sUTn8POJn
38/pI2pxnlt8RtKLrDhwc8rOq5B7+/Qr0P+fWQofuyob8tq79oLezS2/DP2H
ZEEOsWxAC9tN/3ZLleRvx3ep8uQcv457K4cjTgwRuw57plbfl7iRXBJjev1Y
xxbQL78Lf4kJefWgL5xQL3G9S6rC3+p/oAl2WHEC8WmdidfBbi3vAbf73lHi
WWuJZ0h7uqPS7jgEu8/lZEpcz8hvBr/1A2/jfXY7cPvJ8zjrLV/i6S4fliJx
LXe3xvyNWjMGfMhUPw7rM5GX7ozrwN3bhfeUPF2bDnnE+G1t8MfbO3x6kicR
yJOIyK/ELcmZCOQEv66v+HjF1GtMb+wb30Hi1ugGxL/e56xP/1tRusSNrC03
HOKjN8cgv9F7dFNon6hebE/778GIW+3gHuChXmLVccijvVtYqdBX7QJudn/j
KPLgSKvPf9tx6GuvOHTJYTlJL+bD/JX4rB4MfY3SC369C/ibZfNPgm5TjRr/
1UPTwGfd922KnE5/DXw+WNYKPPAvx6dgeTqdrkO+T8uBPcL4tJ++4cIu3Zf7
+R3kBdcH5uMW1eE+0e/AA7wP6oAYkQP7mtmlkCusG5xfzMdamYe4Nx9sQPyG
+cX6KnWY4pz5cL4r+vbY9Dvs0NvXK6wzXK8UebaX7YY/58VBH9Yrzl+m934d
Imf82I+K3VZfOAM7HdsBPcI6xnVboV8bw3tt43nfz0HdNi5qvl3HbfbrdNDv
7GtbUeeNbno7zl5/hP5fNKD/iauvok7KvgP9qd9xXFm/nPLrwpiefh4Ffc2Y
OxbfW8ts2CPsg9xnmY+x5nX4Ty+oR50K+6w96TbkEz2G+fkS9H2eHxR5Sp5A
PzYaxyJOw/mB67+Sd9R/2Z5sB0d72H+5nzI929PRHs4b3K/5Xr3Xr/48sX5m
BeQM+rWb2+jLn5wt4K//maMeZbdEYDcnYrdEYDcn4pdE4BfgFCe4z4sTJ+Lf
ROBfJ2LnRGBnJ6JXItDLieiVCPQCTnEr9ZNxC5ziH/bz4h9yUp0P+wXupToP
OwZ9kPNa8pF5DfkpfyUu8xd2ozoJubw6CXmojkE/r46Bnuoh5PfqIeioviG+
vPqGe6mOAffqGOip3kpc1lvwpTmH443nXsa578A+Xt+BnNTX8J3X14BT/4Jf
vP6Ce6nPOsSH+5FD9MJq9+fLTxfvxTnYCyxNQ96ZeYvXlcvzpewZcV9Uf046
XbGhnOTnucIhOXmeFGR/nlsE+YvnMUF25nlVkF947sU9QRzyPCnxMA55fhPk
L55XYdcg3nieFBQnPPdKPIxD3lPAJ8hHnvPDuoF7aW8K6x7sQHsH7BPkL+8X
0Cuo87w3IY6CvsB7DeQP6gbvZWF9hl60N4X1HO9pfwzjBH6h/TGse3jvzUUS
t+epc5Gco0B/Qp0PhTfXgX+DOq9a3pwAPDon/Bv37TNanUtFSrVv/8icL7y5
AvpG5mfdm3/gx8h+xHmRIH11b07AOTLnmysnYK4xIvuCua6kDHUtsjdpk3P9
+SOyh1qlW6rAP7LXaDumX4EfInuTtm/+SeDRedKbNyBvZE8UXv0BHt27vf4I
/0X2Tdfrs1JOO7Ln2l5flrgZ3cu8vilxLdI3LW9+gL7RPd3rjxJ331T/z2B7
cwL491L/z8D8H8WH72U+j5JHoSe9GGd/KXzIX4JxsifjbH/G2c6Msx8ZZ78z
zvGm4BSfCh+KK8Y5zhX5KU/ZDpx3ih0ofxV6ykflXspHxjnfFT5UZxjnOqP4
K5lEHdPHPfW17GdhXzMmtyEP3Wlzdgb5XuRE8KDuFSHuUjTUEfdydnHAZ4Hs
h/rSVtRDu/EdkWD6ZBK4UZO9OaSPR+hD/s5/DtcfFw==
"], 
{Hue[0.6, 0.3, 0.85], EdgeForm[Hue[0.6, 0.3, 0.75]], 
TagBox[Polygon3DBox[CompressedData["
1:eJwBvwNA/CFib1JiAgAAADoBAAADAAAAAQIDBAUGBwgJCgYLDA0ODw4QERIF
ExAIFAkVFhcYGRobHBUdHgsNHxsgISIXIyAkJSQiJicoKRgqKywtLi0vMC8x
JjIzNDM1Njc4OTgyOjE7PB0aPTU+P0BBQkNERURGRyosSD5DSUFKS0pMTUZA
Tjs3T0xQUVJTE1RVVldYWVpbXFtdXlhaX2BXYWJgY11kZWZkCmdoHmlnB2pU
DGtpEWxtbgNtD1VrFG9qHHBvLnFyGXN0KXV2PHRwH3dzIXh5I3p3JXl6e1BS
FnZ4fFNiMH1xK3J+R351On99OSiAToF/NoCBgoOENIUnSIaHRYiJe4qLTYyI
SY2OS4+NQomGT4uPUZCKY5GSX5OUfJWQP46MVpaTXJKXXpiWWZeYPYeFmZpm
mwMSmxFtnBEFnR5nnh4NnwponQoLnARsYZSVngxpoBMIoQ9rog8Qo4QDoQwO
oAdUpAcJohNVpBRqpRQVpRxvpjwapykqqDxwphl0qR8gqhkbqh9zp0d1qSN3
qyV6rCF5rSEXqyMkrRZ4ril2rCUirhYYBGhsr0cssDY4sS5ysk5/sSstsy4v
tDp9szBxtDAxryt+sjo7qBwdsDmAtTaBtU43tjkytzQntiYotyYzuDQ1uD2F
uT0+unuLu0JEvEVGvE2Iu0WJvUKGvUhDvk1Avj+Mv0uNwEtMwXtSwE+PwkmO
wj9Buk9QwVGKw1FTxFmYxXxixlZYw3yQxWGVx19XyGFgyF+Uv0lKx1aTgoRm
yVlbxF5axl6WyVyXymNky1xdy2OSymaRzAGEFq52EZsSE6BUA5ttzaNuBJ9o
EZxsBJwFB6AICp8GHp0LDJ4NDKFrCp1nD6EOE6IQHp5pD6JVKa4YB6RqI6t6
HKUVH6obFKVvHKhwGaYaPKgdPKZ0FKQJGapzAwISJaskI6kgH6l3Jax5Fq0X
IawiIa14nwQGKad1XsSYOrQxK7FyLrNxMLMvLrEtK68sR69+MLR9OrJ/TrI7
NrCAuUiHObYoObA4JrcnJrYyNLczPbg1P8KOSLk+TbxGPbmHSL2GRbtEQr1D
QruJNrU3RbyINLiFScJBP75ATb6MSb+NT8BMS79KS8CPTrWBT7qLe7pQY8td
fMWVfMNTYciUYcViY8qRX8hgZspkUcOQVsdXWcRaWcmXX8eTXMlbXsZYVsaW
XMuSR6cqzoJlo83Pg4LPg6PPZpqR0AHRbqMDe8GKhAEDAczRzJmE0pnRhJlm
gs7PZYJmo4OEmczRUcFSAdACmdKaydpvxw==
"]],
Annotation[#, "Geometry"]& ]}],
MouseAppearanceTag["LinkHand"]],
AllowKernelInitialization->False],
"MeshGraphics3D",
AutoDelete->True,
Editable->False,
Selectable->False],
Boxed->False,
DefaultBaseStyle->{
      "MeshGraphics3D", FrontEnd`GraphicsHighlightColor -> Hue[0.1, 1, 0.7]},
ImageSize->{Automatic, 101.06325221053599`},
Lighting->{{"Ambient", 
GrayLevel[0.45]}, {"Directional", 
GrayLevel[0.3], 
ImageScaled[{2, 0, 2}]}, {"Directional", 
GrayLevel[0.33], 
ImageScaled[{2, 2, 2}]}, {"Directional", 
GrayLevel[0.3], 
ImageScaled[{0, 2, 2}]}},
Method->{"ShrinkWrap" -> True},
ViewPoint->{1.3, -2.4, 2.},
ViewVertical->{0., 0., 1.}]\)]}
Out[31]=

Get text outlines:

In[32]:=
ResourceFunction["SimplexBoundary"][
 DiscretizeGraphics[Text["Hello world"], _Text]]
Out[32]=

Requirements

Wolfram Language 11.3 (March 2018) or above

Resource History

See Also

License Information