(*------These are the main macro definitions---------------------------------*) Unprotect[Out]; mapshape[f_,s_] := Map[f,s]; (* s is a list of points *) mapshapelist[f_,l_] := Map[mapshape[f,#]&,l]; (* l is a list of lists of points *) ifsshapelist[ifs_,l_] := Flatten[Map[mapshapelist[#,l]&,ifs],1]; (* ifs is a list of maps *) iterateifs[ifs_,shape_,n_] := Nest[ifsshapelist[ifs,#]&,{shape},n]; (*look[ifs_,n_Integer:1]:=iterateifs[ifs,{{x,y}},n] <-- not used any longer *) (* The following function plots the list of shapes to see the fractal pattern. ------------------------------------------------------------------- *) plotifs[ifs_,shape_,n_:3] := Module[{l,glist}, Clear[Out]; l = iterateifs[ifs,shape,n]; glist = Map[Line,l]; Show[Graphics[{Thickness[.0005]}~Join~glist], AspectRatio->Automatic] ]; plotifs::usage = "plotifs[ifs, shape , n] returns a picture of the n-th iterate of the initial shape under the IFS defined in ifs, that should consist of a list of pure functions. Typically, the functions in ifs will be defined using similarity[...], bisimilarity[...] and affine[...]. The last parameter is optional and its value is n=3." (* It is also possible to generate the attractor by a random algorithm. An initial point is given and it is repeatedly transformed by a randomly chosen map from the IFS. An optional number of iterations can be skipped. ----------------------------------------------------------------------------*) Clear[laorbita]; laorbita[ifs_,m_Integer:1000,x0_:{0,0},skip_Integer:50]:= FoldList[Apply[ifs[[#2]],{#1}]&, Fold[Apply[ifs[[#2]],{#1}]&, x0, Table[Random[Integer,{1,Length[ifs]}],{skip}]], Table[Random[Integer,{1,Length[ifs]}],{m}]]; (* The following function uses the random algorithm to plot the attractor of the IFS.---------------------------------------------------------------------*) plotifsrandom[ifs_,m_Integer:1000,x0_:{0,0},skip_Integer:50] := ( ListPlot[laorbita[ifs,m,x0,skip], AspectRatio->Automatic, Axes->False, PlotStyle->{PointSize[.005]}]; Clear[Out]; ) plotifsrandom::usage = "plotifsrandom[ifs, iterates,{x0,y0}, skip] returns a picture of the fractal generated under the IFS defined in ifs. The parameter ifs should consist of a list of pure functions that could be defined using affine[...], similarity[...] and bisimilarity[...]. The fractal in this case is generated by the random method. Skip is the number of points skipped and {x0,y0} is the initial point. The last three arguments are optional, and they have the following default values: iterates=1000, {x0,y0}={0,0}, skip=50." (* It is convenient to have some way to specify the maps of an IFS without typing them in by hand. The function similarity[ ] defined a similarity transformation with a given scaling, translation and rotation. The function bisimilarity[ ] allows two different scaling factors. Finally, affine[ ] takes as input a 2x2 matrix and a translation.-------------------------------------*) similarity[scale_,trans_:{0,0},rot_:0]:= Compile[{{x,_Real,1}}, With[{sc=scale*Cos[Pi*rot/180],ss=scale*Sin[Pi*rot/180]}, {sc*x[[1]]-ss*x[[2]]+trans[[1]],ss*x[[1]]+sc*x[[2]]+trans[[2]]} ]]; similarity::usage= "similarity[scale, {tx,ty}, rotation] defines a pure function that is a similarity transformation with a given scaling (scale), translation ({tx,ty}), and rotation (in degrees). The translation and rotation are optional. Their default values are: {tx,ty}={0,0}, rotation=0." bisimilarity[scale1_,scale2_,trans_:{0,0},rot_:0]:= Compile[{{x,_Real,1}}, With[{sc=scale1*Cos[Pi*rot/180],r=scale2/scale1,ss=scale1*Sin[Pi*rot/180]}, {sc*x[[1]]-r*ss*x[[2]]+trans[[1]],ss*x[[1]]+r*sc*x[[2]]+trans[[2]]} ]]; bisimilarity::usage= "bisimilarity[scale1, scale2, {tx,ty},rotation] defines a pure function that is a bisimilarity transformation with a given scaling (scale1, scale2), translation ({tx,ty}), and rotation (in degrees). The translation and rotation are optional. Their default values are: {tx,ty}={0,0}, rotation=0." affine[mat_,trans_] := Compile[{{x,_Real,1}}, {mat[[1,1]]*x[[1]]+mat[[1,2]]*x[[2]]+trans[[1]], mat[[2,1]]*x[[1]]+mat[[2,2]]*x[[2]]+trans[[2]]} ]; affine::usage= "affine[m, {tx,ty}] defines a pure function that is an affine transformation with matrix m and translation {tx,ty}." (*Here are some Mathematica functions concerned with Iterated Function Systems. An IFS will be a list of functions from the plane to the plane. These should be written so as to take a list x = {x[[1]],x[[2]]} as input and return a new list as output. The fractals will be generated by applying the IFS to an initial shape. Each shape is a polygon defined as a list of points.------------------------------ *) segment = {{0,0},{1,0}}; triangle = {{0,0},{1,0},{0.5,N[Sqrt[3]/2]},{0,0}}; square = {{0,0},{0,1},{1,1},{1,0},{0,0}}; diamond = {{0.5,0},{0,0.5},{-0.5,0},{0,-0.5},{0.5,0}}; (* Here are some IFS which lead to famous fractals.--------------------------*) sff1= similarity[1/2]; sff2= similarity[1/2,{1/2,0}]; sff3= similarity[1/2,{0.25,0.25*Sqrt[3]}]; sierpinski = {sff1,sff2,sff3}; kff1= similarity[1/3]; kff2= similarity[1/3, {1/3,0},60]; kff3= similarity[1/3, {1/2,Sqrt[3]/6},-60]; kff4= similarity[1/3,{2/3,0}]; koch = {kff1,kff2,kff3,kff4}; s5ff1= similarity[1/3]; s5ff2= similarity[1/3, {1/3, 0}]; s5ff3= similarity[1/3, {2/3, 0}]; s5ff4= similarity[1/3, {0, 1/3}]; s5ff5= similarity[1/3, {1/3, 1/3}]; s5ff6= similarity[1/3, {2/3,1/3}]; s5ff7= similarity[1/3, {0,2/3}]; s5ff8= similarity[1/3, { 1/3,2/3}]; s5ff9= similarity[1/3, {2/3,2/3}]; square5= {s5ff1,s5ff3,s5ff5,s5ff7,s5ff9}; squarehole= {s5ff1,s5ff2,s5ff3,s5ff4,s5ff6,s5ff7,s5ff8,s5ff9}; " IFS \n A Mathematica package. \n (C) 1997 Richard Moeckel and Hector Lomeli"