Animacja - przechowywanie zmiennych - 2006-10-26
Przy zapisywaniu wartości do pliku nie zapomnij wstawić na końcu przecinka
wiecej >>

Szukaj: 
Logowanie
Login
Hasło   
Pamiętaj mnie na tej stronie
 Zarejestruj się...




Najnowsza grafika
maxmoon
2012-04-24


Najnowsza tapeta
Nunas
2011-09-15
Piramida kulek - macro

Dla osób, średniozaawansowanych, chcących poznać mechanizm macr, petli i rekurencji

W poprzednim tutorialu opisałem jak stworzyć, piramidę z kulek. W tym przejdziemy trochę dalej, stworzymy taką samą piramidę, ale za pomocą makra.

Macro w POVRAY jest tym czym procedura w Pascalu, albo funkcja w c/c++. Jest to pewien rodzaj funkcji, która wykonuje określone zadania.

Deklaracja makra wygląda tak. Pierwej słowo kluczowe #macro (należy pamiętać o hashu # przed słowami kluczowymi), następnie powinna wystąpić nazwa makra. Nazwa makra jest to dowolny wyraz wymyślony przez nas. Z tą wolnością to nie jest tak prosto, nazwy zmiennych, makr i funkcji podlegają pewnym zasadom.

  • Nazwa nie powinna zaczynać się od cyfr
  • Nazwa nie powinna zawierać znaków specjalnych
  • Nazwa nie powinna zawierać polskich liter

    Przykładowa nazwa. MojaNowaNazwa()
    albo mc_moja_nazwa()

    Po nazwie wstawiamy nawiasy okrągłe (), jeżeli istnieje potrzeba w nawiasach podajemy, listę argumentów. Argument jest to zmienna przyjmująca wartość jaką chcemy przekazać do naszego makra.
    Załóżmy, że chcemy stworzyć makro, które będzie tworzyło ramkę. Chcemy abyśmy mogli określać wymiary ramki (szerokość, wysokość, jak i grubość tej ramki). Nasze makro powinno mieć taką deklarację.
      #macro mc_ramka(wys, szer, gru) 
      // a tu deklaracja makra
      #end
      
    
    Jak widać makro powinno się kończyć słowem kluczowym #end (każda instrukcja blokowa powinna się kończyć słowem #end)

    To tyle wstępu.

    Bierzemy scene z poprzedniego toturiala trochę ją czyścimy i powinniśmy otrzymać coś takiego:
      
      // Persistence of Vision Ray Tracer Scene Description File
      // File: tapeta_kulki.pov
      // Vers: 3.5
      // Desc: Tapeta z fotonowymi kulkami
      // Date: 04/08/05
      // Auth: Adam Druzd
      //
      
      #version 3.5;
      #include "colors.inc"
      #declare Photons=on;
      
      global_settings {
        //assumed_gamma 1.0
        max_trace_level 15
        #if (Photons)          // global photon block
          photons {
            spacing 0.02                 // specify the density of photons
          }
      
        #end
      }
      
      // ----------------------------------------
      
      camera {
        location  <2,30,-35>
        look_at   <2,1,0>
        angle 30
      }
      
      light_source {
        <-500,300,250>       // light's position
        color rgb <1,1,1>       // light's color
        photons {           // photon block for a light source
          refraction on
          reflection on
        }
      }
      
      sky_sphere {
        pigment {
          gradient y
          color_map {
            [0.0 rgb <0.6,0.7,1.0>]
            [0.7 rgb <0.0,0.1,0.8>]
          }
        }
      }
      
      
      plane {
        y, 0
        texture {
          pigment { color Gray }
        }
      }
      
      
      #declare M_Glass=    // Glass material
      material {
        texture {
          pigment {rgbt 1}
          finish {
            ambient 0.0
            diffuse 0.05
            specular 0.6
            roughness 0.005
            reflection {
              0.1, 1.0
              fresnel on
            }
            conserve_energy
          }
        }
        interior {
          ior 1.5
          fade_power 1001
          fade_distance 0.9
          fade_color <0.5,0.8,0.6>
        }
      }
      
    
    Teraz tworzymy nasze makro, chcemy móc określić:
  • Promień naszej kulki
  • Z ilu kulek będzie się składała nasza piramida
  • Początkowa pozycja
  • I materiał z jakiego będą się składać kulki

    Sama deklaracja powinna wyglądać tak.

      #macro mc_piramida_kluek(r, ilosc, poz, mat )
      #end
    
    W naszym makro określimy sobie zmienną a która będzie się równać 2*r, czyli:
      
      #local a=2*r; 
      
    


    Następnie określamy naszą kulkę, o promieniu r i o materiale mat, czyli o takich parametrach jakie zostały przekazane do naszego makro.
      
      #local k=sphere { <0,0,0>,r material { mat } }
      
    


    Jako, że nasza piramida będzie składała się z kilku kulek, łączymy jest w jedną całość użyjemy do tego union:
      union
      {
      // i tu będzie deklaracja naszego makra rysująca kulki
      }
      
    
    Parametr ilość określa ile kulek ma być "na jednym boku" naszej piramidy. Przy przekazaniu wartości trzy otrzymamy taką piramidę.



    Natomiast, jeżeli ile ilosc=2 to nasza piramida będzie wyglądała tak:



    Do tego celu użyjemy pętli #while. Taką pętle konstruujemy w następujący sposób.

      
      #while(warunek)
      // ciało pętli
      #end
      
    

    W nawiasach okrągłych podajemy warunek. Dopóki warunek jest spełniony dopóty to co jest wewnątrz pętli jest wykonywane. Reasumując jeżeli warunek jest zawsze spełniony to pętla jest nieskończona, jeżeli natomiast warunek nigdy nie jest spełniony to pętla nigdy się nie wykona (nie wykona oznacza to iż instrukcje wewnątrz tej pętli nigdy się nie wykonają).

    Teraz utworzymy pętle, która utworzy nam tyle kulek ile przechowuje zmienna ilość, na razie kulki będą ustawione w jednym wierszu. Za każdym obiegiem pętli będzie tworzyć jeden obiekt typu k odpowiednio przesunięty.

      
       union
       {       
            #local ind=0;
             #while(ind<ilosc)
                   object { k translate <poz.x+ind*a,      poz.y+r,        poz.z> }
                  #local ind=ind+1;
           #end
      }
      #end 
    
    Teraz szczegółowy opis:
    Ad1. Wszystkie nasze obiekty będziemy łączyć w jeden obiekt do tego używamy union. W linijce 2 tworzymy zmienną lokalną ind, którą ustalamy początkowo na wartość równą 0. Zmienna ta będzie nam potrzebna do tego, aby ograniczyć działanie pętli. W linijce 4 tworzymy pętle. Tak jak wspomniałem wcześniej w nawiasach okrągłych podajemy warunek i jeżeli jest on spełniony wykonuje się to co jest w pętli. W tym konkretnym przypadku nasz warunek jest tak skonstruowany ind < ilosc , czyli jeżeli ind jest mniejszy od ilosc to warunek jest prawdziwy. Zakładamy, że robimy piramidę z 3 kulkami w podstawie. Tak więc u nas warunek w pierwszy obiegu pętli jest prawdziwy ponieważ.
    Ind=0
    Ilosc=3
    Warunek: ind < ilosc
    czyli: 0 < 3
    Warunek jest spełniony.
    W linijce 5 tworzymy nowy obiekt typu k, i przesuwamy go na odpowiednią pozycję. Tu winien jestem pewne wyjaśnienie.
    Do naszego makro przekazujemy zmienną poz, która dla przykładu równa się <0,0,0>. Wewnątrz makro możemy się do niej odwołać jako do całości pisząc np. translate poz albo do jej składowych: poz.x w ten sposób potrafimy wydobyć wartość składowej x tego wektora. Jeżeli poz=<1,2,3> to poz.x == 1 poz.y==2, a poz.z=3.
    W translate w nawiasach ostrych przekazujemy trzy liczby <x,y,z>. Taki zapisz: poz.x +ind*a można tak rozwinąć. Weź wartość x wektora poz (poz.x) do otrzymanej wartości dodaj iloczyn ind i a. Dlaczego akurat iloczyn ind i a? Zaraz to wyjaśnię, ale pierw o linijce 6. Dla programistów linijka ta jest jasna ale i tak opiszę. Zmiennej ind przypisujemy nową wartość, która będzie się równała starej wartości ind plus jeden, czyli tak zwana inkrementacja. W niektórych językach można to napisać (ind++). W linijce 7 jest słowo kluczowe #end określa nam koniec pętli. Teraz pętla ponownie idzie do słowa while linijka 4. Znowu sprawdzamy warunek.
    Ind=1; -> ponieważ w linijce została jego wartość zwiększona o jeden.
    Ilosc=3; -> zmienna ilosc nie była modyfikowana przechowuje to przechowywała.
    Ind<ilosc -> 1<3 -> warunek spełniony, czyli znowu wykonujemy to co jest w pętli.


    Wróćmy teraz do naszego translate i rozpatrzmy jakie przyjmuje one wartości w zależności od aktualnego kroku pętli,

    Krok 1.
    Ind=0;
    Ilosc=3;
    Warunek spełniony 0<3
    a=2*r=2;
    poz=<0,0,0>, czyli poz.x=0, poz.y=0, poz.z=0
    to nasze translate przyjmuje wartość
    składowa x: 
    poz.x+ind*a czyli 0+0*2=0
    składowa y:
    	poz.y=0
    składowa z:
    	poz.z=0;
    Upraszczając nasze translate w pierwszym kroku wygląda tak:
    	Translate <0,0,0>
    
    Krok 2. 
    Ind=1;
    Ilosc=3
    Warunek spełniony 1<3
    a=2*r=2;
    poz=<0,0,0>, czyli poz.x=0, poz.y=0, poz.z=0
    Nasze transalte 
    Składowa x:
    	Poz.x+ind*a czyli 0+1*2=2;
    Pozostałe składowe pozostają bez zmian. To nasze translate ma postać:
    translate <2,0,0>
    Czyli nasz obiekt został przesunięty wzdłuż osi x o dwa (w prawo)
    
    
    Krok 3.
    Ind=2;
    Ilosc=3
    Warunek spełniony 2<3
    a=2*r=2;
    poz=<0,0,0>, czyli poz.x=0, poz.y=0, poz.z=0
    Nasze transalte 
    Składowa x:
    	Poz.x+ind*a czyli 0+2*2=4;
    Pozostałe składowe pozostają bez zmian. To nasze translate ma postać:
    translate <4,0,0>
    Czyli nasz obiekt został przesunięty wzdłuż osi x o cztery (w prawo)
    
    Krok 4.
    Ind=3;
    Ilosc=3
    Warunek NIE spełniony 3<3 ponieważ ind=ilosc a warunek był, że ma być mniejszy. 
    W konsekwencji tego wylądujemy w linijce  8 (już poza pętlą).
    
    Po wyrenderowaniu powinniśmy otrzymać coś takiego:



    Tu możesz pobrać plik, gotową sceną.

    Bardzo ładnie to wygląda, ale jeszcze długa droga przed nami, a mi się właśnie wykład z BD kończy :-).

    Pętla, którą stworzyliśmy tak naprawdę jest w stanie narysować nam rządek kulek o dowolnej długość, my dążymy jednak do piramidy.

    Teraz postaramy się stworzyć kolejne rzędy, w wielkim uogólnieniu możemy powiedzieć, że kolejny rząd powinniśmy narysować w identyczny sposób jak ten. W programowaniu istnieje taki termin jak pętle zagnieżdżone. Czyli pętla w pętli. Stwórzmy zmienną pomocniczą ind1, która będzie indeksowała nam tą pętle zewnętrzną. Rzędów musi być tyle ile jest kul w naszym wypadku trzy, czyli warunek ind1<ilosc jest i w tym wypadku poprawny. Co więcej ta nasza nowa pętla zewnętrzna będzie odpowiedzialna za tworzenie kulek w nowych rzędach. Albo inaczej to ujmując będzie przesuwała kulki wzdłuż osi z.
    Tak wygląda zapis.

      
      union
      {
             #local ind1=0;
             #while(ind1<ilosc)
                  #local ind=0;
                  #while(ind<ilosc)
             object { k translate <poz.x+ind*a,      poz.y+r,        poz.z+ind1*a> }
             #local ind=ind+1;
                   #end
                   #local ind1=ind1+1;
             #end
       }
      
    
    Plik ze sceną.

    Teraz szybki opis.
    Ad 1 Tworzymy nowy obiekt typu union. Wyjaśnione wyżej,
    Ad 3 Deklarujemy nową zmienną ind1 odpowiedzialną, za kontrolowanie pętli zewnętrznej.
    Ad 4 Początek pętli zewnętrznej odpowiedzialnej za położenie naszej kulki na osi z
    Ad 5 Deklarujemy zmienną ind, która odpowiedzialna jest za kontrolowanie petli wewnętrznej
    Ad 6 Początek pętli wewnętrznej odpowiedzialnej za pozycje naszej kulki na osi x
    Ad 7 Tworzymy nowy obiekt znaczy się kulkę.
    Ad 8 Zwiększamy zmienną lokalną ind o jeden
    Ad 9 Koniec pętli wewnętrznej
    Ad 10 Zwiększamy o jeden zmienną ind1
    Ad 11 Koniec pętli zewnętrznej Ad 12 koniec bloku od union


    No dobra, ale pewnie się zastanawiacie jak to działa. To ja zadam inne pytanie, jak myślicie ile kroków jest wykonywanych w tych pętlach. Albo inaczej ile kulek zostanie stworzonych przy założeniu, że ilosc=3. Jako, że to jest mój monolog to pozwolę sobie na to odpowiedzieć. 9 kulek zostanie stworzonych. Tak naprawdę to są trzy kroki pętli zewnętrznej, a w każdej tej pętli trzy kroki pętli wewnętrznej, co nam daje 3*3=9; Kroki pętli wewnętrznej będą określane rzymskimi cyframi a kroki wewnętrznej pętli cyframi arabskimi. Render wygląda tak:



    Teraz prześledźmy jak to działa. Dla polepszenia czytelności nie będę pisał, przy każdy kroku, że ilosc=3, bo wartość tej zmiennej nie ulega zmianie w czasie przebiegu pętli. A w nawiasach okrągłych podane są linijki w której jesteśmy w programie.
    ind1=0; (3)
    ind1<ilosc, 0<3; czyli warunek spełniony, tak więc wchodzimy do pętli zewnętrznej
    Krok I. 
     (4)
    	ind=0; (5)
    
    	ind<ilosc; 0<3; czyli warunek spełniony, tak więc wchodzimy do pętli wewnętrznej (6)
    	Krok 1.
    		składowa x: poz,x+ind*a = 0+0*2 = 0
    		składowa y: poz.y+r = 0+1=1
    		składowa z: poz.z+ind1*a = 0+0*2 = 0 
    		czyli transalte <0,1,0> (7)
    		ind=ind+1 = 0+1 = 1, zwiększamy ind o jeden w wracamy do początku pętli.
    	Ind<ilosc; 1<3 warunek spełniony
    		Krok 2.
    		składowa x: poz,x+ind*a = 0+1*2 = 2
    		składowa y: poz.y+r = 0+1=1
    		składowa z: poz.z+ind1*a = 0+0*2 = 0 
    		czyli transalte <2,1,0> (7)
    		ind=ind+1 = 1+1 = 2, zwiększamy ind o jeden w wracamy do początku pętli.
    	Ind<ilosc; 2<3 warunek spełniony
    	Krok 3.
    		składowa x: poz,x+ind*a = 0+2*2 = 4
    		składowa y: poz.y+r = 0+1=1
    		składowa z: poz.z+ind1*a = 0+0*2 = 0 
    		czyli transalte <4,1,0> (7)
    		ind=ind+1 = 2+1 = 3, zwiększamy ind o jeden w wracamy do początku pętli.
    	Ind<ilosc; 3<3 warunek NIE spełniony przechodzimy na koniec pętli wewnętrznej (9)
    	Ind1=ind1+1; 0+1=1, zwiększamy ind1 o jeden
    	ind1<ilosc, 1<3; czyli warunek spełniony, tak więc wchodzimy do pętli zewnętrznej
    Krok II. 
    	 (4)
    	ind=0; (5)
    
    	ind<ilosc; 0<3; czyli warunek spełniony, tak więc wchodzimy do pętli wewnętrznej (6)
    	Krok 1.
    		składowa x: poz,x+ind*a = 0+0*2 = 0
    		składowa y: poz.y+r = 0+1=1
    		składowa z: poz.z+ind1*a = 0+1*2 = 2 
    		czyli transalte <0,1,2> (7)
    		ind=ind+1 = 0+1 = 1, zwiększamy ind o jeden w wracamy do początku pętli.
    	Ind<ilosc; 1<3 warunek spełniony
    	Krok 2.
    		składowa x: poz,x+ind*a = 0+1*2 = 2
    		składowa y: poz.y+r = 0+1=1
    		składowa z: poz.z+ind1*a = 0+1*2 = 2 
    		czyli transalte <2,1,2> (7)
    		ind=ind+1 = 1+1 = 2, zwiększamy ind o jeden w wracamy do początku pętli.
    	Ind<ilosc; 2<3 warunek spełniony
    	Krok 3.
    		składowa x: poz,x+ind*a = 0+2*2 = 4
    		składowa y: poz.y+r = 0+1=1
    		składowa z: poz.z+ind1*a = 0+1*2 = 2 
    		czyli transalte <4,1,2> (7)
    		ind=ind+1 = 2+1 = 3, zwiększamy ind o jeden w wracamy do początku pętli.
    	Ind<ilosc; 3<3 warunek NIE spełniony przechodzimy na koniec pętli wewnętrznej (9)
    	Ind1=ind1+1; 1+1=2, zwiększamy ind1 o jeden
    	ind1<ilosc, 2<3; czyli warunek spełniony, tak więc wchodzimy do pętli zewnętrznej
    Krok III. 
    	 (4)
    	ind=0; (5)
    
    	ind<ilosc; 0<3; czyli warunek spełniony, tak więc wchodzimy do pętli wewnętrznej (6)
    	Krok 1.
    		składowa x: poz,x+ind*a = 0+0*2 = 0
    		składowa y: poz.y+r = 0+1=1
    		składowa z: poz.z+ind1*a = 0+2*2 = 4 
    		czyli transalte <0,1,4> (7)
    		ind=ind+1 = 0+1 = 1, zwiększamy ind o jeden w wracamy do początku pętli.
    	Ind<ilosc; 1<3 warunek spełniony
    		Krok 2.
    		składowa x: poz,x+ind*a = 0+1*2 = 2
    		składowa y: poz.y+r = 0+1=1
    		składowa z: poz.z+ind1*a = 0+2*2 = 4 
    		czyli transalte <2,1,4> (7)
    		ind=ind+1 = 1+1 = 2, zwiększamy ind o jeden w wracamy do początku pętli.
    	Ind<ilosc; 2<3 warunek spełniony
    	Krok 3.
    		składowa x: poz,x+ind*a = 0+2*2 = 4
    		składowa y: poz.y+r = 0+1=1
    		składowa z: poz.z+ind1*a = 0+2*2 = 4 
    		czyli transalte <4,1,4> (7)
    		ind=ind+1 = 2+1 = 3, zwiększamy ind o jeden w wracamy do początku pętli.
    	Ind<ilosc; 3<3 warunek NIE spełniony przechodzimy na koniec pętli wewnętrznej (9)
    	Ind1=ind1+1; 1+1=2, zwiększamy ind1 o jeden
    	Ind1<ilosc; 3<3 warunek NIE spełniony przechodzimy na koniec pętli zewnętrznej (11)
    
    W ten oto sposób prześledziliśmy krok po kroku działanie programu. W efekcie czego uzyskaliśmy piękną macierz, tablice kulek o wymiarach 3x3. Troszkę minęliśmy się z naszym zamysłem. No właśnie a co było naszym zamysłem? Utworzenie piramidy której podstawą byłby trójkąt o bokach ilosc x ilosc, a nie macierz o bokach ilosc x ilosc. Określmy co jest nie tak. W drugim obiegu pętli zewnętrznej, powinny rysować się dwie kulki a nie trzy, czyli o jedną mniej, natomiast w trzecim obiegu pętla zewnętrzna powinna się wykonywać tylko raz. Przypomnijmy jeszcze co determinuje ilość wykonywania się pętli wewnętrznej, jest to warunek ind<ilosc gdzie u nas ind przyjmuje kolejno wartość od zera w górę. Za każdym obiegiem pętli zewnętrznej ind zostaje ustawione na wartość 0. My musimy w jakiś sposób uzależnić warunek pętli wewnętrznej od zmienne ind1 czyli od kroku pętli zewnętrznej. Możemy to uczynić zmieniając linijkę 5 z #local ind=0; na #local ind=ind1; Po wyrenderowaniu otrzymamy coś takiego.



    Już bardzo blisko teraz wystarczy trochę kulki cofnąć w lewą stronę i już powinno być ok. Tylko jak, w poprzednim tutorialu napisałem, że kulki w drugim rzędzie muszą być przesunięte w stosunku do pierwszego o r, czyli o promień kulki. No tak, ale jak wstawimy po prostu -r w składowej x to nam nic nie da. Bo zarówno pierwszy rząd będzie przesunięty o -r jaki i drugi, jak i trzeci. Czyli tak naprawdę całość zostanie przesunięta w prawo o wartość r. A spróbujmy to przesunięcie uzależnić od wartość ind1 czyli naszego licznika pętli zewnętrznej.
    Zapisujemy to tak:
      object { k translate <poz.x+ind*a-ind1*r,      poz.y+r,        poz.z+ind1*a> }
    
    A po zrenderowaniu wygląda to tak:



    Teraz tylko drobna kosmetyczna poprawka z wartością składowej z.
      
      object { k translate <poz.x+ind*a-ind1*r,      poz.y+r,        poz.z+ind1*a*sqrt(3)/2> }
      
    
    Dokładne wyjaśnienie obliczenia składowej z podałem w poprzednim tutorialu.


    Plik z gotową sceną.

    Dobrze wiemy jak utworzyć pierwszy poziom. Trójkąt o zadanej ilości kulek z boku. Teraz zastanówmy się jak stworzyć piramidę. Myślę, że jeżeli powiemy co to takiego taka piramida to rozwiązanie samo przyjdzie do głowy. To pozwólcie, że ja zdefiniuje taką piramidę.
    Piramida jest to zbiór kulek poukładanych w trójkąty, tak że każdy taki trójkąt znajdujący się nad innym składa się z kulek o jedna mniej.



    Zauważcie, że pierwsza warstwa naszej piramidy składa się z trójkąta w którym w jednym boku są 3 kulki. Druga warstwa z trójkąta, który bok ma złożony z 2 kulek, a trzecia warstwa z "trójkąta" o boku równym 1 :-). A trójkąty to my rysować potrafimy.
    To pozostaje nam po prostu wywołać nasze makro tyle razy ile ma być warstw. Aby to osiągnąć użyjemy mechanizm rekurencji. Rekurencja to jest wywoływanie się makra samego siebie :-). Rekurencja jest bardzo potężnym narzędziem, daje wiele możliwości. Jednak bardzo łatwo się w niej pogubić i zapętlić. My w celu uniknięcia zapętlenia, czyli wykonywania ciągłego, wstawimy jeden warunek wywołania rekurencji, a mianowicie, że ilosc musi być większe od 1.
    Nasze gotowe makro wygląda tak:
      
      #macro mc_piramida_kluek(promien, ilosc, poz, mat )
      #local r=promien;
      #local a=2*r;
      #local k=sphere { <0,0,0>,r material { mat }  }
      union
      {
      #local ind1=0;
      #while(ind1<ilosc)
      #local ind=ind1;
      #while(ind<ilosc)
      object { k translate <poz.x+ind*a-ind1*r,      poz.y+r,        poz.z+ind1*a*sqrt(3)/2> }
      #local ind=ind+1;
      #end
      #local ind1=ind1+1;
      #end
      #if(ilosc>1)
      #local poz1=<poz.x+r, poz.y+a*sqrt(2/3), poz.z+(a*sqrt(3)/6)>;
      object { mc_piramida_kluek(r, (ilosc-1) ,poz1, mat) }
      #end
      }
      #end
      
    
    W porównaniu z poprzednią wersją naszego makra doszły 4 linijki
      
      1.#if(ilosc>1)
      2.     #local poz1=<poz.x+r, poz.y+a*sqrt(2/3), poz.z+(a*sqrt(3)/6)>;
      3.     object { mc_piramida_kluek(r, (ilosc-1) ,poz1, mat) }
      4.#end
      
    


    Co one robią? W linijce 1 sprawdzamy czy ilosc jest większa od 1. Tak jak wspomniałem jest to zabezpieczenie tego, aby makro nie wykonywało się w nieskończoność. W linijce 2 określamy nową pozycję początkową dla następnej warstwy (dokładny algorytm wyznaczania współrzędnych opisałem w poprzednim tutorialu). W linijce 3 wywołujemy nasze makro ponownie. Z tym, że zmniejszamy ilość kulek o 1 (ilosc-1) i przekazujemy nową pozycję startową. To co? Teraz przydało by się krok po kroku opisać jak to się wykonuje? No to skrótowo, będę podawał tylko wartości ilosc, ind, ind1 :-)

    Uruchamiamy makro i przekazujemy ilosc=3; No to start

    Ilosc=3;
    Ind1=0;
    Ind1<ilosc; 0<3
    	Ind=ind1;
    	Ind<ilosc; 0<3
    		// tworzymy kulkę obliczając współrzędne
    		Ind=ind+1; 0+1=1
    	Ind=1;
    	Ind<ilosc; 1<3
    		// tworzymy kulkę obliczając współrzędne
    		Ind=ind+1; 1+1=2
    	Ind=2;
    	Ind<ilosc; 2<3
    		// tworzymy kulkę obliczając współrzędne
    		Ind=ind+1; 2+1=3
    	Ind>ilosc wracamy do pętli zewnętrznej.
    Ind1=ind1+1; 0+1=1;
    Ind1<ilosc; 1<3
    	Ind=ind1;
    	Ind<ilosc; 1<3
    		// tworzymy kulkę obliczając współrzędne
    		Ind=ind+1; 1+1=2
    	Ind=2;
    	Ind<ilosc; 2<3
    		// tworzymy kulkę obliczając współrzędne
    		Ind=ind+1; 2+1=3
    	Ind>ilosc wracamy do pętli zewnętrznej.
    Ind1=ind1+1; 1+1=2;
    Ind1<ilosc; 2<3
    	Ind=Ind2;
    	Ind<ilosc; 2<3
    		// tworzymy kulkę obliczając współrzędne
    		Ind=ind+1; 2+1=3
    	Ind>ilosc wracamy do pętli zewnętrznej.
    Ind1=ind1+1; 2+1=3;
    Ind1>ilosc przechodzimy wychodzimy z pętli
    Ilosc>1 3>1 prawda wchodzimy do ifa.
    Określamy nową pozycję startową i uruchamiamy makro Ale ilosc-1=3-1=2
    
    Ilosc=2;
    Ind1=0;
    Ind1<ilosc; 0<2
    	Ind=ind1;
    	Ind<ilosc; 0<2
    		// tworzymy kulkę obliczając współrzędne
    		Ind=ind+1; 0+1=1
    	Ind=1;
    	Ind<ilosc; 1<2
    		// tworzymy kulkę obliczając współrzędne
    		Ind=ind+1; 1+1=2
    	Ind>ilosc wracamy do pętli zewnętrznej.
    Ind1=ind1+1; 0+1=1;
    Ind1<ilosc; 1<2
    	Ind=ind1;
    	Ind<ilosc; 1<2
    		// tworzymy kulkę obliczając współrzędne
    		Ind=ind+1; 1+1=2
    	Ind>ilosc wracamy do pętli zewnętrznej.
    Ind1=ind1+1; 2+1=3;
    Ind1>ilosc przechodzimy wychodzimy z pętli
    Ilosc>1 2>1 prawda wchodzimy do ifa.
    Określamy nową pozycję startową i uruchamiamy makro Ale ilosc-1=2-1=1
    
    Ilosc=1;
    Ind1=0;
    Ind1<ilosc; 0<1
    	Ind=ind1;
    	Ind<ilosc; 0<1
    		// tworzymy kulkę obliczając współrzędne
    		Ind=ind+1; 0+1=1
    	
    	Ind>ilosc wracamy do pętli zewnętrznej.
    Ind1=ind1+1; 0+1=1;
    Ind1>ilosc przechodzimy wychodzimy z pętli
    Ilosc>1 1>1 FAŁSZ Wychodzimy z makra
    
    Ta dam!! Nasze makro pięknie działa.
  • A tu jest gotowy plik ze sceną i makrem do ściągnięcia.
  • A tu jest gotowy plik ze sceną i fotonami do ściągnięcia
  • © druidy.pl

    Korzystając z witryny bez zmiany ustawień przeglądarki wyrażasz zgodę na użycie plików cookies. W każdej chwili możesz swobodnie zmienić ustawienia przeglądarki decydujące o ich zapisywaniu.