# # Generating a Siepinski gasket. # # # First, we have a procedure that takes one triangle as input, and returns three triangles with a side length of half the original. # This is the basic generation step for the gasket. # # Note that it returns 3 triangles, NOT a list of 3 triangles. > OneToThree:=proc(tri)\ local mid1, mid2, mid3;\ \ mid1:=[(tri[1][1]+tri[2][1])/2,(tri[1][2]+tri[2][2])/2];\ mid2:=[(tri[2][1]+tri[3][1])/2,(tri[2][2]+tri[3][2])/2];\ mid3:=[(tri[3][1]+tri[1][1])/2,(tri[3][2]+tri[1][2])/2];\ \ RETURN( [tri[1], mid1, mid3, tri[1] ],\ [mid1, tri[2], mid2, mid1 ],\ [mid2, tri[3], mid3, mid2 ]);\ end:\ \ # gasket takes a list of triangles as input, and applies OneToThree to each triangle. It then repeats the process on THAT list, numsteps times. # > gasket:=proc(start,numsteps)\ local triangles, i, k;\ \ triangles:=start;\ for i from 1 to numsteps do\ triangles:=[seq(OneToThree(triangles[k]), k=1..nops(triangles))];\ od;\ \ RETURN(triangles);\ end:\ \ # Finally, we have a handy utility routine that allows us to plot several disjoint curves (our triangles) on the same plot, with no axes. > PlotCurves:= proc(curvelist)\ local i;\ plots[display](\ PLOT( seq(CURVES(curvelist[i]),i=1..nops(curvelist))),\ axes=none,scaling=constrained);\ end:\ -------------------------------------------------------------------------------- # # Now we are ready to make a Sierpinski gasket. # # FirstTri is an equlateral triangle of side length 2, which we use for our "level 0" gasket. > FirstTri := evalf([ [0,0], [1,sqrt(3)], [2,0], [0,0] ]):\ PlotCurves([FirstTri]);\ ** Maple V Graphics ** # We can now refine this a few times to get a level 3 gasket: > l3:= gasket([FirstTri], 3):\ PlotCurves(l3);\ ** Maple V Graphics ** # # If we want, we can use the previous figure (l3) as input, and refine it further. Thus, the following should give us a level 6 gasket: # > l6:= gasket(l3 , 3):\ PlotCurves(l6); ** Maple V Graphics ** -------------------------------------------------------------------------------- # # # Had we been so inclined, we could have written the gasket procedure recursively instead of iteratively. Here is one way to do that: # # # > cheese:=proc(trilist,n)\ local i;\ \ if (n<=0) then \ RETURN(op(trilist));\ else\ RETURN( seq(cheese([OneToThree(trilist[i])], n-1),\ i=1..nops(trilist)));\ fi;\ \ end:\ \ # This works by using OneToThree to triple each triangle in the list, as gasket does. It then calls itself on the resulting list of 3 triangles, asking for # one level less of decoration. When the number of levels to go gets to zero, the input is returned (stripped of one level of nesting). # # As a consequence, notice that the output is a bunch of triangles, NOT a list of triangles as in gasket. This means that we have to wrap the # result in brackets before we can feed it into PlotCurves. # # "cheese" is not a better way than "gasket" to make the Sierpinski gasket; they are just two different ways of doing the same thing. # Here is the result. > PlotCurves([cheese([FirstTri],6)]);\ ** Maple V Graphics ** > > \