# IFS fractal constructor # by A.Drozd restart; # here we initialize our environment col:=black: counter:=0: total:=0: # global variables initialization SetColor:=proc() local ttc,tc,r,g,b,ctmp; global col: ttc:=Maplets:-Tools:-Get('CD1'): tc:=sscanf(ttc,"#%x"): b:=irem(tc[1],256,'ctmp'): b:=b/255: g:=irem(ctmp,256,'r'): g:=g/255: r:=r/255: col:=COLOR(RGB,r,g,b): # This procedure takes color value from color dialog in string format # then transforms it into maple color structure # and passes it to global variable 'col' . end: #indicate_iterations proc calculates and display number of iterations #of fractal calculation algorithm with current settings indicate_iterations:=proc() local depth,fract,total,ttotal,i,ifs,ts; depth:=Maplets:-Tools:-Get('SL1'): fract:=Maplets:-Tools:-Get('LB1'): ifs:=M[fract]: total:=1: if depth>1 then ttotal:=seq(nops(ifs)^i, i=1..depth): total:=sum(ttotal[i],i=1..depth): fi: if depth=1 then total:=nops(ifs): fi: Maplets:-Tools:-Set('progress'('foreground')=black): if total>10000 then Maplets:-Tools:-Set('progress'('foreground')=red): fi: ts:=sprintf("iter:%d",total): Maplets:-Tools:-Set('progress'=ts): end: #this routine indicates progress of current computation indicate_progress :=proc() local ts,p; global counter: p:=trunc(evalf(100*counter/total)): ts:=sprintf("%d%%",p): Maplets:-Tools:-Set('progress'=ts): end: #core function of fractal calculation transform_point := proc(t, p) [t[1]*p[1]+t[2]*p[2]+t[5], t[3]*p[1]+t[4]*p[2]+t[6]] end: #this procedure takes one triangle and transform it into new group transforme_triangle := proc(t, triangle) local i; global counter; counter:=counter+1: if irem(counter,50)=1 then indicate_progress(): fi: [seq(transform_point(t, triangle[i]), i=1 .. 3)] end: # IFS generates fractal from current presets: # it is based on transform_triangle routine and returnes # ready-made plot strucure IFS := proc(n, liste_de_transformations) local i, j, k, s, sequence_de_triangles,result,ttotal,pg_flag: global counter,total: options `Here we go`: counter:=0: total:=1: if n>1 then ttotal:=seq(nops(liste_de_transformations)^i, i=1..n); total:=sum(ttotal[i],i=1..n); fi: sequence_de_triangles := [[0, 0], [1, 0], [0.5, 1]]; for j to n do s := NULL; for i to nops(liste_de_transformations) do s := s, seq(transforme_triangle(liste_de_transformations[i], op(k, [sequence_de_triangles])), k=1 .. nops([sequence_de_triangles])) od; sequence_de_triangles := s od; pg_flag:=Maplets:-Tools:-Get('ChB1'); Maplets:-Tools:-Set('progress'="100%"): if pg_flag then result:=plots[polygonplot]([sequence_de_triangles], axes=none, color=col, scaling=constrained,style=patchnogrid) else result:=plots[polygonplot]([sequence_de_triangles], axes=none, color=col, scaling=constrained,style=patch) fi: end: # M table contains coordinates of triangles defining different fractals # which are accessible by their aliases M:=table ([ "tamis_Sierpinski"= [[0.5,0,0,0.5,0,0],[0.5,0,0,0.5,0.5,0],[0.5,0,0,0.5,0.25,0.5] ], "arbre_Noel_double"= [[0,-.5,.5,0,.5,0],[0,.5,-.5,0,.5,.5],[.5,0,0,.5,.25,.5] ], "labyrinthe_Sierpinski"= [[evalf(1/3),0,0,evalf(1/3),evalf(1/3),evalf(2/3)], [0,evalf(1/3),1,0,evalf(2/3),0], [0,-evalf(1/3),1,0,evalf(1/3),0] ], "rameau"= [[.387,.430,.430,-.387,.2560,.5220], [.441,-.091,-.009,-.322,.4219,.5059], [-.468,.020,-.113,.015,.4,.4] ], "cristal"= [[.255,0,0,.255,.3726,.6714],[.255,0,0,.255,.1146,.2232], [.255,0,0,.255,.6306,.2232],[.37,-.642,.642,.37,.6356,-.0061] ], "mecano"= [[.382,0,0,.382,.3072,.619],[.382,0,0,.382,.6033,.4044], [.382,0,0,.382,.0139,.4044],[.382,0,0,.382,.1253,.0595], [.382,0,0,.382,.492,.0595] ], "feu"= [[evalf(1/3),0,0,evalf(1/3),0,0], [evalf(1/6),evalf(-sqrt(3)/6),evalf(sqrt(3)/6),evalf(1/6),evalf(1/3),0], [evalf(-1/6),evalf(-sqrt(3)/6),evalf(sqrt(3)/6),evalf(-1/6), evalf(2/3),0], [evalf(1/3),0,0,evalf(1/3),evalf(2/3),0] ], "arbre"= [[.195,-.488,.344,.443,.4431,.2452], [.462,.414,-.252,.361,.2511,.5692], [-.058,-.07,.453,-.11,.5976,.0969], [-.035,.07,-.469,-.022,.4884,.5069], [-.637,0,0,.501,.8562,.2513] ], "maple"= [[0.29, 0.4, -0.4, 0.3, 0.28, 0.44], [0.33, -0.34, 0.39, 0.4, 0.41, 0], [0.42, 0, 0, 0.63, 0.29, 0.36], [0.61, 0, 0, 0.61, 0.19, 0.23], [0.01, 0, 0, 0.29, 0.5, 0.13] ], "tab15"= [[-0.04, 0, -0.23, -0.65, -0.08, 0.26], [0.61, 0, 0, 0.31, 0.07, 2.5], [0.65, 0.29, -0.3, 0.48, 0.54, 0.39], [0.64, -0.3, 0.16, 0.56, -0.56, 0.4] ], "koch"= [[evalf(1/3), 0, 0, evalf(1/3), 0, 0], [evalf(1/3), 0, 0, evalf(1/3), evalf(2/3),0], [evalf(1/6),evalf(-sqrt(3)/6),evalf(sqrt(3)/6),evalf(1/6),evalf(1/3),0], [-evalf(1/6),evalf(sqrt(3)/6),evalf(sqrt(3)/6),evalf(1/6),evalf(2/3),0] ], "tab21"= [[0, 0, 0, 0.5, 0, 0], [0.4, -0.4, 0.4, 0.4, 0, 0.2], [0.4, 0.4, -0.4, 0.4, 0, 0.2] ] ]): # auxiliary procedure to start fractal generation launcher:=proc() local depth,fract,starttime,endtime,ifs,str1,tp; depth:=Maplets:-Tools:-Get('SL1'): fract:=Maplets:-Tools:-Get('LB1'): starttime:=time(): ifs:=IFS(depth,M[fract]): endtime:=time(): str1:=sprintf("in %2.2f sec.", endtime-starttime): with(plots); #tp:=textplot([0.1,0,str1],align={BELOW,RIGHT},color=blue): #display(ifs,tp): Maplets:-Tools:-Set('progress'=str1): ifs: end: # showinfo() showes new window with initial set of triangles # which define current fractal showinfo:=proc() local fract,ifs,ret,ts,tts,i,j,co; fract:=Maplets:-Tools:-Get('LB1'); ifs:=M[fract]: ifs:=M[fract]: ts:="": for i to nops(ifs) do co:=ifs[i]: tts := sprintf("%2.2f",co[1]); ts:=cat(ts,"(",tts,", "): if co[1]>=0 then ts:=cat(ts," "): fi: tts := sprintf("%2.2f",co[2]); if (co[2]>=0) then ts:=cat(ts,tts,"), "): else ts:=cat(ts,tts,"), ") fi: tts := sprintf("%2.2f",co[3]); ts:=cat(ts,"(",tts,", "): if (co[3]>=0) then ts:=cat(ts," "): fi: tts := sprintf("%2.2f",co[4]); if (co[4]>=0) then ts:=cat(ts,tts,"), "): else ts:=cat(ts,tts,"), ") fi: tts := sprintf("%2.2f",co[5]): ts:=cat(ts,"(",tts,", "): if co[5]>=0 then ts:=cat(ts," "): fi: tts := sprintf("%2.2f",co[6]); ts:=cat(ts,tts,")\n"): od: # ret:="Here goes this damned fracal description": Maplets:-Tools:-Set('TB5'=ts); #system( "start ifs.hlp" ); end: with(Maplets[Elements]): #Form1 is maplet-based interface for fractal constructor Form1:='Form1': Form1:=Maplet ('onstartup' = 'start', Window['main'] ( layout=BoxLayout ( inset=0, BoxColumn (spacing=0, BoxRow ( "Select fractal type", DropDownBox['LB1'] (onchange='A2', foreground=black,sort ([seq(op(indices(M)[i]),i=1..nops([indices(M)]))], lexorder ) ), Button[B3]("i",onclick='A3',tooltip="info about current fractal") ), BoxRow ( BoxLayout(border=true,inset=0,Plotter['PL1'](background=white)) ), BoxRow ( "Depth:", Slider['SL1'](0..8, 4, 'showticks', 'majorticks'=2, 'minorticks'=1, 'snapticks'=true,filled=true,onchange='A2'), BoxColumn ( BoxRow('halign'='left', TextField['progress']("progress",width=8,editable=false, tooltip="Progress indicator") ), BoxRow('halign'='left', CheckBox['ChB1']("patchnogrid") ) ) ), BoxRow ( Button['B1']("Process",onclick='A1'), Button("Color", onclick=RunDialog('CD1'),tooltip="Select color"), Button("About", RunWindow('about')), Button("Close", Shutdown("Have a nice day!"),tooltip="Close this maplet") ) ) ) ), Action['A1']( SetOption('B1'(enabled)='false'), Evaluate (PL1='launcher()'), SetOption('B1'(enabled)='true') ), Action['A2']( Evaluate (function='indicate_iterations()'), Evaluate (function='showinfo()') ), Action['A3']( Evaluate (function='indicate_iterations'), RunWindow('MD2'), Evaluate (function ='showinfo()') ), Action['start'](RunWindow('main')), MessageDialog['MD1']( "IFS fractal constructor by A.Drozd", 'type'='information' ), Window['MD2']( title="fractal info", ["This fractal is generated from this set of triangles", TextBox[TB5](editable=false,value="N/A",height=6,width=50), Button("Ok",CloseWindow('MD2')) ] ), Window['about']( title="About fractal constructor", ["(c) 2004 Alexander Drozd", [Label(Image("myfaceBW.jpg")),TextBox[TB6](editable=false,value=" Fractal constructor is powerful softaware for exploring triangular fractals written by Alexander Drozd under the direction of senior teacher S.N. Avvakumov", height=6,width=30)], Button("Ok",CloseWindow('about')) ] ), ColorDialog['CD1']( 'onapprove' = Evaluate(function="SetColor") ) ): # Maplets[Display](Form1);