+ Construction

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                      *)