Skip to main content
added 381 characters in body
Source Link

In version 11, one has ShellRegion[] that is supposedly useful for 3D printers who want to save on material. Its performance on the spikey leaves something to be desired, tho:

Show[ShellRegion[PolyhedronData["Spikey", "BoundaryMeshRegion"], 1/20],
     BaseStyle -> Opacity[0.5]]

hollow spikey as a region


In version 11, one has ShellRegion[] that is supposedly useful for 3D printers who want to save on material. Its performance on the spikey leaves something to be desired, tho:

Show[ShellRegion[PolyhedronData["Spikey", "BoundaryMeshRegion"], 1/20],
     BaseStyle -> Opacity[0.5]]

hollow spikey as a region

deleted 5 characters in body
Source Link
(* barycenter of a polygon *)
averagepoints[points_?MatrixQ] :=
        Mean[If[TrueQ[First[points] == Last[points]], Most, Identity][points]]

(* Newell's algorithm for face normals *)
newellNormals[pts_?MatrixQ] := Module[{tp = Transpose[pts]}, Normalize[MapThread[Dot,
              {RotateLeft[ListConvolve[{{-1, 1}}, tp, {-1, -1}]], 
               RotateRight[ListConvolve[{{1, 1}}, tp, {-1, -1}]]}]]]

thickenaux[points_, outer_, thick_] := Module[{center = averagepoints[points],
  nrm = newellNormals[points], outerpoints, radialpoints},
  outerpoints = Map[(center - thick nrm + outer (# - center)) &, points];
  radialpoints = MapThread[Join[Reverse[#1], #2] &,
                           Map[Partition[#, 2, 1, {1, 1}]1] &, {points, outerpoints}]];
  Flatten[{Polygon[points], Polygon /@ radialpoints, Polygon[Reverse[outerpoints]]}]]

ThickenPolygons[shape_, outer_: 0.8, thick_: 0.04] := 
 shape /. Polygon[p_?MatrixQ] :> thickenaux[p, outer, thick]
(* barycenter of a polygon *)
averagepoints[points_?MatrixQ] :=
        Mean[If[TrueQ[First[points] == Last[points]], Most, Identity][points]]

(* Newell's algorithm for face normals *)
newellNormals[pts_?MatrixQ] := Module[{tp = Transpose[pts]}, Normalize[MapThread[Dot,
              {RotateLeft[ListConvolve[{{-1, 1}}, tp, {-1, -1}]], 
               RotateRight[ListConvolve[{{1, 1}}, tp, {-1, -1}]]}]]]

thickenaux[points_, outer_, thick_] := Module[{center = averagepoints[points],
  nrm = newellNormals[points], outerpoints, radialpoints},
  outerpoints = Map[(center - thick nrm + outer (# - center)) &, points];
  radialpoints = MapThread[Join[Reverse[#1], #2] &,
                           Map[Partition[#, 2, 1, {1, 1}] &, {points, outerpoints}]];
  Flatten[{Polygon[points], Polygon /@ radialpoints, Polygon[Reverse[outerpoints]]}]]

ThickenPolygons[shape_, outer_: 0.8, thick_: 0.04] := 
 shape /. Polygon[p_?MatrixQ] :> thickenaux[p, outer, thick]
(* barycenter of a polygon *)
averagepoints[points_?MatrixQ] :=
        Mean[If[TrueQ[First[points] == Last[points]], Most, Identity][points]]

(* Newell's algorithm for face normals *)
newellNormals[pts_?MatrixQ] := Module[{tp = Transpose[pts]}, Normalize[MapThread[Dot,
              {RotateLeft[ListConvolve[{{-1, 1}}, tp, {-1, -1}]], 
               RotateRight[ListConvolve[{{1, 1}}, tp, {-1, -1}]]}]]]

thickenaux[points_, outer_, thick_] := Module[{center = averagepoints[points],
  nrm = newellNormals[points], outerpoints, radialpoints},
  outerpoints = Map[(center - thick nrm + outer (# - center)) &, points];
  radialpoints = MapThread[Join[Reverse[#1], #2] &,
                           Map[Partition[#, 2, 1, 1] &, {points, outerpoints}]];
  Flatten[{Polygon[points], Polygon /@ radialpoints, Polygon[Reverse[outerpoints]]}]]

ThickenPolygons[shape_, outer_: 0.8, thick_: 0.04] := 
 shape /. Polygon[p_?MatrixQ] :> thickenaux[p, outer, thick]
added 1576 characters in body
Source Link
(* barycenter of a polygon *)
averagepoints[points_?MatrixQ] :=
        Mean[If[TrueQ[First[points] == Last[points]], Most, Identity][points]]

(* Newell's algorithm for face normals *)
newellNormals[pts_?MatrixQ] := Module[{tp = Transpose[pts]}, Normalize[MapThread[Dot,
              {RotateLeft[ListConvolve[{{-1, 1}}, tp, {-1, -1}]], 
               RotateRight[ListConvolve[{{1, 1}}, tp, {-1, -1}]]}]]]

thickaux[points_thickenaux[points_, outer_, thick_] := Module[{center = averagepoints[points],
  nrm = newellNormals[points], outerpoints, radialpoints},
  outerpoints = Map[(center - thick nrm + outer (# - center)) &, points];
  radialpoints = MapThread[Join[Reverse[#1], #2] &,
                           Map[Partition[#, 2, 1, {1, 1}] &, {points, outerpoints}]];
  Flatten[{Polygon[points], Polygon /@ radialpoints, Polygon[Reverse[outerpoints]]}]]

ThickenPolygons[shape_, outer_: 0.8, thick_: 0.04] := 
 shape /. Polygon[p_?MatrixQ] :> thickaux[pthickenaux[p, outer, thick]

I set the defaults in ThickenPolygons[] to work for tetrahedra; for other polyhedra or for parametrically-defined surfaces, you might need to play around with the values for the parameters outer and thick.


Here's an alternate version, which might be more suitable for polyhedra than the previous version:

thickenaux[points_, outer_, fac_] := 
 Module[{center = averagepoints[points], nrm = newellNormals[points], n, outerpoints,
         radialpoints, thick},
  n = Length[points] - Boole[TrueQ[First[points] == Last[points]]];
  thick = fac (1 - outer) Mean[Norm[# - center] & /@ points];
  outerpoints = Map[(center - thick nrm + outer (# - center)) &, points];
  radialpoints = MapThread[Join[Reverse[#1], #2] &, 
    Map[Partition[#, 2, 1, {1, 1}] &, {points, outerpoints}]];
  Flatten[{Polygon[points], Polygon /@ radialpoints, Polygon[Reverse[outerpoints]]}]]

ThickenPolygons[shape_, outer_: 0.8, fac_: Sqrt[2]/4] := 
 shape /. Polygon[p_?MatrixQ] :> thickenaux[p, outer, fac]

If you run this version of ThickenPolygons[] on spikeyCut and carefully inspect the coordinates, you'll see that the points in the inner walls match up perfectly; there are neither gaps nor unintentional polygon intersections.

The proper value of fac to use will depend on the polyhedron being considered. For the Platonic solids ($\phi$ denotes the golden ratio),

\begin{array}{c|c} \text{polyhedron}&\class{code}{\text{fac}}\\\hline \text{cube}&\frac1{\sqrt 2}\\ \text{dodecahedron}&\frac{1+\phi}{2}\\ \text{icosahedron}&\frac{1+\phi}{2}\\ \text{octahedron}&\frac1{\sqrt 2}\\ \text{tetrahedron}&\frac1{2\sqrt 2} \end{array}

The default value used for fac works for the tetrahedron and the spikey.

(* barycenter of a polygon *)
averagepoints[points_?MatrixQ] :=
        Mean[If[TrueQ[First[points] == Last[points]], Most, Identity][points]]

(* Newell's algorithm for face normals *)
newellNormals[pts_?MatrixQ] := Module[{tp = Transpose[pts]}, Normalize[MapThread[Dot,
              {RotateLeft[ListConvolve[{{-1, 1}}, tp, {-1, -1}]], 
               RotateRight[ListConvolve[{{1, 1}}, tp, {-1, -1}]]}]]]

thickaux[points_, outer_, thick_] := Module[{center = averagepoints[points],
  nrm = newellNormals[points], outerpoints, radialpoints},
  outerpoints = Map[(center - thick nrm + outer (# - center)) &, points];
  radialpoints = MapThread[Join[Reverse[#1], #2] &,
                           Map[Partition[#, 2, 1, {1, 1}] &, {points, outerpoints}]];
  Flatten[{Polygon[points], Polygon /@ radialpoints, Polygon[Reverse[outerpoints]]}]]

ThickenPolygons[shape_, outer_: 0.8, thick_: 0.04] := 
 shape /. Polygon[p_?MatrixQ] :> thickaux[p, outer, thick]

I set the defaults in ThickenPolygons[] to work for tetrahedra; for other polyhedra or for parametrically-defined surfaces, you might need to play around with the values for the parameters outer and thick.

(* barycenter of a polygon *)
averagepoints[points_?MatrixQ] :=
        Mean[If[TrueQ[First[points] == Last[points]], Most, Identity][points]]

(* Newell's algorithm for face normals *)
newellNormals[pts_?MatrixQ] := Module[{tp = Transpose[pts]}, Normalize[MapThread[Dot,
              {RotateLeft[ListConvolve[{{-1, 1}}, tp, {-1, -1}]], 
               RotateRight[ListConvolve[{{1, 1}}, tp, {-1, -1}]]}]]]

thickenaux[points_, outer_, thick_] := Module[{center = averagepoints[points],
  nrm = newellNormals[points], outerpoints, radialpoints},
  outerpoints = Map[(center - thick nrm + outer (# - center)) &, points];
  radialpoints = MapThread[Join[Reverse[#1], #2] &,
                           Map[Partition[#, 2, 1, {1, 1}] &, {points, outerpoints}]];
  Flatten[{Polygon[points], Polygon /@ radialpoints, Polygon[Reverse[outerpoints]]}]]

ThickenPolygons[shape_, outer_: 0.8, thick_: 0.04] := 
 shape /. Polygon[p_?MatrixQ] :> thickenaux[p, outer, thick]

I set the defaults in ThickenPolygons[] to work for tetrahedra; for other polyhedra or for parametrically-defined surfaces, you might need to play around with the values for the parameters outer and thick.


Here's an alternate version, which might be more suitable for polyhedra than the previous version:

thickenaux[points_, outer_, fac_] := 
 Module[{center = averagepoints[points], nrm = newellNormals[points], n, outerpoints,
         radialpoints, thick},
  n = Length[points] - Boole[TrueQ[First[points] == Last[points]]];
  thick = fac (1 - outer) Mean[Norm[# - center] & /@ points];
  outerpoints = Map[(center - thick nrm + outer (# - center)) &, points];
  radialpoints = MapThread[Join[Reverse[#1], #2] &, 
    Map[Partition[#, 2, 1, {1, 1}] &, {points, outerpoints}]];
  Flatten[{Polygon[points], Polygon /@ radialpoints, Polygon[Reverse[outerpoints]]}]]

ThickenPolygons[shape_, outer_: 0.8, fac_: Sqrt[2]/4] := 
 shape /. Polygon[p_?MatrixQ] :> thickenaux[p, outer, fac]

If you run this version of ThickenPolygons[] on spikeyCut and carefully inspect the coordinates, you'll see that the points in the inner walls match up perfectly; there are neither gaps nor unintentional polygon intersections.

The proper value of fac to use will depend on the polyhedron being considered. For the Platonic solids ($\phi$ denotes the golden ratio),

\begin{array}{c|c} \text{polyhedron}&\class{code}{\text{fac}}\\\hline \text{cube}&\frac1{\sqrt 2}\\ \text{dodecahedron}&\frac{1+\phi}{2}\\ \text{icosahedron}&\frac{1+\phi}{2}\\ \text{octahedron}&\frac1{\sqrt 2}\\ \text{tetrahedron}&\frac1{2\sqrt 2} \end{array}

The default value used for fac works for the tetrahedron and the spikey.

missing bracket
Source Link
Loading
Source Link
Loading