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, 34.

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:

PIC
Stadio 0

PIC
Stadio 1

PIC
Stadio 2

PIC
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:

PIC
PIC
PIC
PIC

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

PIC