The Menger Sponge, named after Karl Menger, is a three dimensional analog of a gasket. The following cell defines a function called Sponge that produces the stages in the construction of the Menger Sponge.
Input := (* Given a level as input, the function Sponge outputs a picture of the Menger Sponge at that level of construction. Code adapted from code written by Robert M. Dickau available at MathSource (http://www.wri.com/WWWDocs/mathsource/) *) Clear[Sponge,level,iters,side,cubmat,i,j,k,n,faces] Sponge[level_Integer?NonNegative]:= Module[{iters,side,cubmat,i,j,k,n,faces}, iters = level; side = 3. ^ iters ; cubmat (* cuboid-matrix *) = Table[ If[i==side + 1. || j==side + 1. || k==side + 1., (* Pad the table's edges with zeroes; if you want to see the complement of the sponge, transpose the 0. and 1. directly below. *) 0., 1.], {i,1.,side + 1.},{j,1.,side+1.},{k,1.,side+1.}]; Do[ If[ (Mod[Round[i/3.^n + 0.5],3]==2 && (Mod[Round[j/3.^n + 0.5],3]==2 || Mod[Round[k/3.^n + 0.5],3]==2)) || (Mod[Round[j/3.^n + 0.5],3]==2 && (Mod[Round[i/3.^n + 0.5],3]==2 || Mod[Round[k/3.^n + 0.5],3]==2)) || (Mod[Round[k/3.^n + 0.5],3]==2 && (Mod[Round[i/3.^n + 0.5],3]==2 || Mod[Round[j/3.^n + 0.5],3]==2)), (* then--taking advantage of eightfold symmetry--... *) (cubmat[[i,j,k]]=0.; cubmat[[side+1-i,j,k]]=0.; cubmat[[i, side+1-j,k]]=0.; cubmat[[i,j,side+1-k]]=0.; cubmat[[side+1-i, side+1-j,k]]=0.; cubmat[[side+1-i,j,side+1-k]]=0.; cubmat[[i, side+1-j, side+1-k]]=0.; cubmat[[side+1-i,side+1-j,side+1-k]]=0.;) (* ...no cuboid goes there *)], {i,(side+1)/2},{j,(side+1)/2},{k,(side+1)/2}, {n,0.,iters-1.}]; faces = {}; (* Instead of using the Cuboid graphics primitive, we show only the polygons visible from viewpoints in the default octant. *) Do[ If[ cubmat[[i,j,k]]==1. && cubmat[[i,j,k+1.]]==0. (* That is, if a face belongs at {i,j,k} and there's nothing hiding it, add the appropriate polygon to the list. *), AppendTo[ faces, (* cuboid tops... *) {{i,j,k+1.},{i,j+1.,k+1.}, {i+1.,j+1.,k+1.},{i+1.,j,k+1.}} ] ], {i,1.,side},{j,1.,side},{k,1.,side} ]; (* Since the figure looks the same regardless of which axis is vertical, the polygon-corner list "faces" is computed only for the tops of the cuboids, then rotated twice to get lists of sides and fronts. *) faces = Join[ faces (*tops*), (*sides *) Map[ RotateLeft[#,2]&,faces,{2}], (*fronts*) Map[ RotateLeft[#,1]*{1,-1,1}+{0,side+2,0}&, faces,{2}] ]; Show[Graphics3D[ {EdgeForm[], Map[ Polygon, faces ]}], Boxed->False]; ]
Construction of the Menger Sponge begins with a solid cube and involves an iterative process of removing parts of this cube. Call the initial cube M0. M1 is obtained by dividing M0 into 27 identical smaller cubes and taking out the center cube and the 6 cubes that represent the middle of each face of MO (for a total of 7 cubes removed). M2 is constructed by repeating the same process (dividing each subcube of M1 into 27 smaller cubes and removing 7 of them). Continuing in this way, we produce a nested sequence of configurations Mn, whose intersection is the limiting sponge, M. M is the self-similar fractal known as the Menger Sponge.
The following cells produce successive levels in the construction of the sponge.
Input := Sponge[0]
Input := Sponge[1]
Input := Sponge[2]
Input := Sponge[3] (* Warning: This picture took 2 minutes, 51 seconds to generate on an SGI Indy *)