13.2 Dua pritrakto: solida objekto de 4-a ordo

La antaŭa programo havas kiel ĉefan avantaĝon ekspluati la nature rekursivan strukturon de la fraktala solido. Rimarku ke tiu sama metodo povas esti uzata ankaŭ por generi aliajn fraktalajn solidojn aŭ, pli simple, aliajn fraktalajn kurbojn. Ĉiuokaze, la tuja konsekvenco de la rekursiva pritrakto estas mallonga fontokodo kaj simple komprenebla. Bedaŭrinde, rimarku ke spongo je 3-a ordo postulas jam 48000 kvadratojn. Necesas tiam estigi la memoron dediĉitan al XLogo je 256 MB en la fenestro pri preferoj por ke la programo povu ruliĝi tute.

Se oni deziras grafiki Menger-an spongon je 4-a ordo, baldaŭ oni estos barita de forĉerpado de memoro. En ĉi tiu parto ni vidos programon bazitan sur tute malsama algoritmo; ĝi ebligos krei spongon de Menger je ordo 0, 1, 2, 3 aŭ 4.

13.2.1 La tapiŝo de Sierpinski

La spongo de Menger estas efektive ĝeneraligon en 3 dimensioj de ebena figuno nomata tapiŝo de Sierpinski. Jen la unuaj iteracioj de tiu figuro:

pict

Stadio 0
pict

Stadio 1
pict

Stadio 2
pict

Stadio 3

La motivo estanta sur ĉiu faco de spongo de Menger je ordo p-a estas tapiŝo de Sierpinski je ordo p-a.

13.2.2 Grafiki tapiŝon de Sierpinski je ordo p-a

La celo estas atingi malpligrandigi la nombron de postulitaj kvarlateroj por desegni tapiŝon de Sierpinski. La jena ekzemplo klarigas la la procedon uzitan por krei tapiŝon de Sierpinski je ordo 3-a. Ĉi tie, la komenca kvadrato konsistas do el 33 = 27 horizontaloj kaj 27 vertikaloj. Oni skribas je bazo 3 la numeron de ĉiu horizontalo kaj ĉiu vertikalo.

Tiam finiĝas la konstruado de la tapiŝo de Sierpinski je ordo 3-a. Por krei tiun tapiŝon necesis uzi entute: 16 + 16 + 32 + 16 = 80 ortangulojn.

13.2.3 Malsamaj skemoj de vertikaloj eblaj

Por resumi la antaŭan konstruadon, jen la malsamaj tipoj de skemaj de vertikaloj laŭ ilia numero. (La simbolo * indikas la ciferon 0 aŭ la ciferon 2.

Numero de la tipo Skemo aplikenda
*** 27
1** 9 9 9
*1* 3 3 6 3 6 3 3
11* 3 3 3 9 3 3 3

Sur la sama principo, por krei tapiŝon je ordo 4-a, oni uzu kvadraton kun 34 = 81 ĉeloj. La numeroj de horizontaloj kaj vertikaloj havos do 4 ciferojn en ilia prezentado je bazo 3. Por ĉiu tipo de numero, jen la skemo aplikenda (la simbolo * indikas la ciferon 0 aŭ la ciferon 2):

Numero de tipo Skemo aplikenda
**** 81
1*** 27 27 27
*1** 9 9 18 9 18 9 9
**1* 3 3 6 3 6 3 6 3 6 3 6 3 6 3 6 3 6 3 3
*11* 3 3 3 9 3 3 6 3 3 9 3 3 6 3 3 9 3 3 3
1*1* 3 3 6 3 6 3 3 27 3 3 6 3 6 3 3
11** 9 9 9 27 9 9 9
111* 3 3 3 9 3 3 3 27 3 3 3 9 3 3 3


496 kvarlateroj estas do necesaj por grafiki tapiŝon de Sierpinski je ordo 4.

Finfine, jen la konstruskemoj por solidoj je ordo 2:

Numero de tipo Skem’ aplikenda
** 9
1* 3 3 3

13.2.4 La programo

 # Grafikas tapi^son de Sierpinski je ordo :p kaj je amplekso :amplekso
 por tapiŝo :amplekso :p
 provizu "unuo :amplekso / (potencon 3 :p)
 se :p=0 [ort :amplekso :amplekso haltu]
 se :p=1 [ripetu 4 [ort :amplekso :unuo an :amplekso dn 90] haltu]
 ripetupor (list "x 1 potencon 3 :p)
   [lokp "cantorx cantor :x :p []
   # Ne grafiku la erojn havantajn unu 1 en la lasta loko
   se  ne (1 = lastan :cantorx)
     [lokp "nom valorigu senlastan :cantorx "
      grafiku_vertikalon :x econ_sendu "map :nom]]
 fino
 
 # Donas la nombron x je bazo 3
 # p profundeca indekso 3^p
 # :list listo malplena ĉe l’ komenco
 
 por cantor :x :p :list
 se :p=0 [sendu :list]
 lokp "a potencon 3 :p-1
 se :x <= :a
   [sendu cantor :x :p-1 frazon :list 0]
   [se :x <= 2*:a [sendu cantor  :x-:a :p-1 frazon :list 1]
    sendu cantor :x - 2*:a :p-1 frazon :list 0]
 fino
 
 # Grafiku la x-an vertikalon laŭ la konstruskemo difinita en la listo
 por grafiku_vertikalon :x :list
   l  dn 90 an (:x-1)*:unuo mdn 90 ml des :list
   l mdn 90 an (:x-1)*:unuo mdn 90 an :x*:unuo dn 90 ml des :list
 l mdn 90 man :x*:unuo ml
 fino
 
 # Grafiku ortangulon laŭ donitaj dimensioj
 # Ĝin registras la 3d-vidilo
 por ort :lo :la
 provizu "nombrilo :nombrilo + 1
 por_edro
 ripetu 2 [an :lo dn 90 an :la dn 90]
 fino_edro
 fino
 
                                                                                                  
                                                                                                  
 # Pretigu la malsamajn eblajn vertikalojn por la tapiŝoj je ordo 1 al 4
 por pretmap
 econ_provizu "map 111 [3 3 3 9 3 3 3 27 3 3 3 9 3 3 3]
 econ_provizu "map 110 [9 9 9 27 9 9 9]
 econ_provizu "map 101 [3 3 6 3 6 3 3 27 3 3 6 3 6 3 3]
 econ_provizu "map 011 [3 3 3 9 3 3 6 3 3 9 3 3 6 3 3 9 3 3 3]
 econ_provizu "map 000 [81]
 econ_provizu "map 100 [27 27 27]
 econ_provizu "map 010 [9 9 18 9 18 9 9]
 econ_provizu "map 001 [3 3 6 3 6 3 6 3 6 3 6 3 6 3 6 3 6 3 3]
 econ_provizu "map  01 [3 3 6 3 6 3 3]
 econ_provizu "map  00 [27]
 econ_provizu "map  10 [9 9 9]
 econ_provizu "map  11 [3 3 3 9 3 3 3]
 econ_provizu "map   1 [3 3 3]
 econ_provizu "map   0 [9]
 fino
 
 # Se la prezento estas [1 0 1] --> sendu 101
 por valorigu :list :vort
   se malplena? :list [sendu :vort]
   [lokp "vort vort :vort unuan :list
    sendu valorigu senunuan :list :vort]
 fino
 
 # Desegnu la ortangulojn de ĉiu vertikalo alterne
 por des :list
 lokp "sumo 0
 ripetupor (list "i 1 kmpt :list)
    [lokp "ero eron :i :list
     lokp "sumo :ero + :sumo
     se para? :i [l an :ero*:unuo ml] [ort :ero*:unuo :unuo an :ero*:unuo]]
 l man :sumo * :unuo ml
 fino
 
 # Testu ĉu nombro estas para
 por para? :i
 sendu 0 = reston :i 2
 fino
 
 por siertapiŝo :p
 ev perspektive tdk pretmap
 provizu "nombrilo 0
 tapiŝo 810 :p
 tajpu "Nombro\ de\ kvarlateroj:\  s :nombrilo
 vue3d
 fin

siertapiŝo 3 desegnas tapiŝon de Sierpinski je ordo 3 kaj latero 810. Jen, ni pretas pasi al la spongo de Menger!

13.2.5 La spongo de Menger je ordo 4

La spongo de Menger havas plurajn simetriecajn atributojn. Por generi ĝin ni grafikos la diversajn sekciojn laŭ la ebeno (xOy), poste portos tiujn figurojn laŭ (yOz) kaj (xOz). Por bone klarigi tion kio okazas, ni restu sur l’ ekzemplo de la spongo je ordo 3:

Kiam oni tranĉas la spongon laŭ vertikala ebeno, oni povas akiri kvar malsamajn motivojn:

pict

pict

pict

pict

Por grafiki spongon je ordo 3, ni trairos la nombrojn de 1 ĝis 27, tio estas, de 001 ĝis 222 je bazo 3. Por ĉiu numero, oni aplikos la taŭgan sekcion kiun oni portos laŭ la 3 direktoj (Ox), (Oy) kaj (Oz).

La kodo

La jena programo permesas grafiki la solidojn de Menger je ordoj 0, 1, 2, 3, 4. La nombro de proceduroj estas grava, do mi klarigos tuj.

 # Grafiki tapiŝon de Sierpinski je ordo :p kaj je amplekso :amplekso
 por  tapiŝo :amplekso :p
 provizu "unuo :amplekso / (potencon 3 :p)
 se :p=0 [ort :amplekso :amplekso haltu]
 se :p=1 [ripetu 4 [ort :amplekso :unuo an :amplekso dn 90] haltu]
 ripetupor (list "x 1 potencon 3 :p)
   [lokp "cantorx cantor :x :p []
    # Ne grafiku erojn havantajn unu 1 en la lasta loko
    se  ne (1 = lastan :cantorx)
      [lokp "nom valorigu senlastan :cantorx "
       grafikuvertikalon :x econ_sendu "map :nom]]
 fino
 
 # Sendu la prezenton je bazo 3 de la nombro x
 # p profundeca indekso 3^p
 # :list listo malplena ĉe l’ komenco
 
 por cantor :x :p :list
 se :p=0 [sendu :list]
 lokp "a potencon 3 :p-1
                                                                                                  
                                                                                                  
 se :x <= :a
   [sendu cantor :x :p-1 frazon :list 0]
   [se :x <= 2*:a [sendu cantor :x-:a :p-1 frazon :list 1]
    sendu cantor :x-2*:a :p-1 frazon :list 2]
 fino
 
 # Grafiku la numeron x laŭ la konstruskemo difinita en la listo
 por grafikuvertikalon :x :list
   l  dn 90  an (:x-1)*:unuo mdn 90 ml des :list
   l mdn 90  an (:x-1)*:unuo  dn 90 an :x*:unuo dn 90 ml des :list
   l mdn 90 man :x*:unuo ml
 fino
 
 # Grafiku ortangulon laŭ donitaj dimensiojn
 # La plurlatero estas registrita de la 3d-vidigilo
 por ort :lo :la
   provizu "nombrilo :nombrilo+1
   por_edro
     ripetu 2 [an :lo dn 90 an :la dn 90]
   fino_edro
 fino
 
 # Komencu la malsamajn vertikalojn eblajn por la tapiŝojn je ordo 1 ĝis 4
 por pretmap
 econ_sendu "map 111 [3 3 3 9 3 3 3 27 3 3 3 9 3 3 3]
 econ_sendu "map 110 [9 9 9 27 9 9 9]
 econ_sendu "map 101 [3 3 6 3 6 3 3 27 3 3 6 3 6 3 3]
 econ_sendu "map 011 [3 3 3 9 3 3 6 3 3 9 3 3 6 3 3 9 3 3 3]
 econ_sendu "map 000 [81]
 econ_sendu "map 100 [27 27 27]
 econ_sendu "map 010 [9 9 18 9 18 9 9]
 econ_sendu "map 001 [3 3 6 3 6 3 6 3 6 3 6 3 6 3 6 3 6 3 3]
 econ_sendu "map  01 [3 3 6 3 6 3 3]
 econ_sendu "map  00 [27]
 econ_sendu "map  10 [9 9 9]
 econ_sendu "map  11 [3 3 3 9 3 3 3]
 econ_sendu "map   1 [3 3 3]
 econ_sendu "map   0 [9]
 fino
 
 # Se la prezento estas [1 0 1] --> sendu 101
 # Se la prezento estas [1 0 2] --> sendu 100
 # La eroj de la listo estas kunmetataj en vorton.
 # Krome, la 2 estas anstataŭataj de nuloj
 por valorigu :list :vort
   se malplena? :list [sendu :vort]
     [lokp "unua unuan :list
      se :unua=2 [lokp "unua 0]
      lokp "vort vort :vort :unua
      sendu valorigu senunuan :list :vort]
 fino
 
 # Desegnu la ortangulojn de ĉiu vertikalo alterne
                                                                                                  
                                                                                                  
 por des :list
 lokp "sumo 0
 ripetupor (liston "i 1 kmpt :list)
    [lokp "ero eron :i :list
     lokp "sumo :ero+:sumo
     se para? :i [l an :ero*:unuo ml] [ort :ort*:unuo :unuo an :ero*:unuo]]
 l man :sumo * :unuo ml
 fino
 
 # Testu ĉu nombro estas para
 por para? :i
   sendu 0 = resto :i 2
 fino
 
 por siertapiŝo :p
   ev perspektive tdk pretmap
   provizu "nombrilo 0
   tapiŝo 810 :p
   tajpu "Nombro\ de\ plurlateroj:\  s :nombrilo
   tridimensie_vidigu
 fino
 
 # Forigas la lastan 1 en la listo :list
 por forigulastanunu :list
   ripetupor (list "i kmpt :list 1 minusigan 1)
     [lokp "ero eron :i :list
      se :ero=1 [lokp "list anstataŭigu :list :i 0 haltu] [se :ero=2 [haltu]]]
   sendu :list
 fino
 
 # Spongo de Menger je amplekso donita kaj je profundeco :p
 
 por menger :amplekso :p
 provizu "unuo :amplekso / (potencon 3 :p)
 ripetupor (list "z 1 potencon 3 :p)
   [lokp "cantorz cantor :z :p []
    lokp "last lastan :cantorz
    lokp "cantorz senlantan :cantorz
    se :last=0 [lokp "ordo valorigu forigulastanunu :cantorz "] [lokp "ordo valorigu :cantorz "]
    lokp "ordo vort "tranĉi :ordo
    graf3tapiŝon :amplekso :ordo :z
    l supren 90 an :unuo malsupren 90 ml]
 graf3tapiŝon :amplekso :ordo (potencon 3 :p) + 1
 fino
 
 # Grafiku la tapiŝojn de Sierpinski je ordo :p
 # laŭ ĉiu akso (Ox), (Oy) et (Oz)
 # je la alto :z
 pour draw3carpet :size :order :z
   l originen
   supren 90 an (:z-1)*:unuo malsupren 90 ml
   skolp bluan ekzek :ordo :amplekso
   l originen
                                                                                                  
                                                                                                  
   mdfn 90 an (:z-1)*:unuo malsupren 90 ml
   skolp flavan ekzek :ordo :amplekso
   l originen
   supren 90 an :amplekso dn 90 an (:z-1)*:unuo malsupren 90 ml
   skolp violruĝan ekzek :ordo :amplekso
 fino
 
 # Ĉefa proceduro
 # Grafiku spongon de Menger je profundeco :p
 por spongo :p
   ev perspektive tdk
   lokp "tempo tempon
   pretmap
   provizu "nombrilo 0
   se :p=0 [kubo 405] [menger 405 :p]
   # Skribu la tempon kaj la nombron de plurlateroj necesaj por konstrui
   tajpu "Nombro\ de\ plurlateroj:\  s :nombrilo
   tajpu "Tempo\ uzita:\  s tempon - :tempo
   tridimensie_vidigu
 fino
 
 # Sekcio por la Menger je ordo 2
 
 por tranĉi1 :amplekso
   ripetu 4 [tapiŝu :amplekso/3 1 l an :amplekso dn 90 ml]
 fino
 
 por tranĉi0 :amplekso
   tapiŝo :amplekso 2
 fino
 
 # Sekcio por la Menger je ordo 3
 
 por tranĉi10 :amplekso
   ripetu 4 [tapiŝo :amplekso/3 2 l an :amplekso dn 90 ml]
 fino
 
 por tranĉi01 :amplekso
   ripetu 4 [ripetu 2 [tranĉi1 :amplekso/3 l an :amplekso/3 ml] an :amplekso/3 dn 90]
 fino
 
 por tranĉi11 :amplekso
   ripetu 4 [tranĉi1 :amplekso/3 l an :amplekso dn 90 ml]
 fino
 
 por tranĉi00 :amplekso
   tapiŝo :amplekso 3
 fino
 
 # Sekcio por la Menger je ordo 4
 
 por tranĉi000 :amplekso
   tapiŝo :amplekso 4
                                                                                                  
                                                                                                  
 fino
 
 por tranĉi100 :amplekso
   ripetu 4 [tapiŝo :amplekso/3 3 l an :amplekso dn 90 ml]
 fino
 
 por tranĉi010 :amplekso
   ripetu 4 [ripetu 2 [tranĉi10 :amplekso/3 l an :amplekso/3 ml] an :amplekso/3 dn 90]
 fino
 
 por tranĉi001 :amplekso
   ripetu 4 [ripetu 2 [tranĉi01 :amplekso/3 l an :amplekso/3 ml] an :amplekso/3 dn 90]
 fino
 
 por tranĉi110 :amplekso
   ripetu 4 [tranĉi10 :amplekso/3 l an :amplekso ml dn 90]
 fino
 
 por tranĉi111 :amplekso
   ripetu 4 [tranĉi11 :amplekso/3 l an :amplekso dn 90 ml]
 fino
 
 por tranĉi101 :amplekso
   ripetu 4 [tranĉi01 :amplekso/3 l an :amplekso dn 90 ml]
 fino
 
 por tranĉi011 :amplekso
   ripetu 4 [ripetu 2 [tranĉi11 :amplekso/3 l an :amplekso/3 ml] an :amplekso/3 dn 90]
 fino
 
 por tranĉi :amplekso
   tapiŝo :amplekso 1
 fino
 
 por kubo :amplekso
   ripetu 2
     [skolp bluan  ort :amplekso :amplekso l an :amplekso malsupren 90 ml
      skolp flavan ort :amplekso :amplekso l an :amplekso malsupren 90 ml]
   skolp violruĝan
   l mdfn 90 mdn 90 an :amplekso dn 90 ml ort :amplekso :amplekso
   l dn 90 an :amplekso mdn 90 dfn 90 dn 90 an :amplekso mdn 90 dfn 90 ml ort :amplekso :amplekso
   mdfn 90 mdn 90 an :amplekso dn 90
 fino
 
 por kuboj
   ev perspektive tdk
   lokp "tempo tempon
   pretmap
   provizu "nombrilo 0
   ripetu 4 [se komputu = 1 [kubo 405] [menger 405 komputu-1] l an 1000 dn 90 ml]
   # Montru la tempon uzitan kaj la nombron de plurlateroj necesaj por konstrui
   tajpu "Nombro\ de\ plurlateroj:\  s :nombrilo
   tajpu "Tempo\ uzita:\  s tempon - :tempo
                                                                                                  
                                                                                                  
   tridimensie_vidigu
 fino

Nun, establu la memoron rezervitan por XLOGO je 640 MiB: spongo 4

pict