Vlákno názorů k článku Izoplochy v POV-Rayi aneb vizuální matematika od anonym - Nerozumím tomu vytváření CSG pomocí izoploch, kde se...

  • Článek je starý, nové názory již nelze přidávat.
  • 15. 5. 2008 17:01

    anonymní
    Nerozumím tomu vytváření CSG pomocí izoploch, kde se používaj funkce min a max. Jak může min(A+B) definovat plochu? Podle mého min vrací jednu hodnotu a to minimální hodnotu funkce A+B? Jak fungují min a max?
  • 15. 5. 2008 17:34

    Pavel Tišnovský
    Zlatý podporovatel
    Pokusím se to vysvětlit na příkladu.

    Dejme tomu, že první funkce A je:

    x^2+y^2+z^2-100

    druhá funkce B je:

    (x-2)^2+y^2+z^2-25

    a threshold je nastaven na nulu.

    Řekněme, že se bude renderovat pouze první funkce A, druhá vůbec nebude v izoploše použita. Takže raytracer vrhá paprsky do scény a testuje, ve kterém místě paprsek protne místo v prostoru, kde platí x^2+y^2+z^2-100=threshold=0. Pokud k protnutí dojde, vykreslí se na daném místě pixel v závislosti na textuře povrchu izoplochy, v opačném případě se vykreslí pozadí, což je nějaká šachovnice. Všechny body splňující podmínku f(x,y,z)=threshold=0 tvoří v našem případě kouli o poloměru 10 se středem ležícím v počátku.

    Pokud by se renderovala pouze druhá funkce B, vytvořila by se koule po poloměru 5 posunutá o 2 jednotky ve směru x-ové osy.

    Teď co se stane, když například obě funkce zkombinujeme pomocí min? Vykreslí se všechny _viditelné_ body, které splňují podmínku pro první funkci (koule o poloměru 10) i body splňující podmínku pro funkci druhou, tj. posunutá menší koule. Protože pro nějaké x,y,z může být sice první funkce nenulová, ale druhá bude nulová, což se pomocí min "stáhne" :-) směrem k nule. Pro body ležící mimo obě plochy je to jedno, tam vyjdou záporná čísla tak jako tak.
  • 15. 5. 2008 18:54

    Pavel Tišnovský
    Zlatý podporovatel
    Sorry, ta poslední věta je špatně, body pro něž je hodnota funkce menší než threshold, leží uvnitř, ne vně. Možná bych to dokázal lépe ilustrovat na programu, pokud by byl zájem. Jaký programovací jazyk preferujes?
  • 16. 5. 2008 11:36

    anonymní
    Asi nejlepší by byl jazyk C nebo syntaktické konstrukce, které ho hodně připomínají.

    Tvůj výklad myslím chápu. Ale jestli jsem to pochopil opravdu dobře, tak pak zápis v tabulce min(A+B) je spíš min{A(x,y,z),B(x,y,z)} pro x,y,z z obalové množiny contained_by. Znaménko plus teda není součet funkcí A a B, ale něco trochu jiného.

    Ostatně teď jsem se podíval mnohem pozorněji na CSG příklad rozdílu a je to jasné:
    max(fn_A(x, y, z), -fn_B(x, y, z)). Je tam čárka. :-) Teď je mi to zcela jasné.

    Děkuji za výklad. Zmátla mě ta tabulka. Já osobně bych spíše očekával něco jako min(A,+B), max (A,+B) a max(A,-B).
  • 16. 5. 2008 14:02

    Pavel Tišnovský
    Zlatý podporovatel
    Sorry, ta carka se mi pri tvorbe tabulky nekam ztratila, takto to je opravdu matouci. Pozadam o opravu a diky za upozorneni.
  • 17. 5. 2008 19:38

    Pavel Tisnovsky (neregistrovaný)

    Tak jsem se konecne dostal k tomu programku. Tady je - po spusteni se vytvori BMP soubor v rozliseni 256x256 pixelu (me oblibene rozliseni :-) a na nem by mel byt zluty srpek mesice. Tj. pouziva se operace rozdilu mezi dvojici kruhu:

    #include <stdio.h>
    #include <stdlib.h>
    #define XMAX 256
    #define YMAX 256
    #define SIZE (XMAX*YMAX*3)
    
    void putpixel(unsigned char *array, int x, int y, unsigned char r, unsigned char g, unsigned char b)
    {
        unsigned char *p=array+(x+y*XMAX)*3;
        *p++=r; *p++=g; *p=b;
    }
    
    void save(const char *filename, const unsigned char *array)
    {
        static unsigned char header[54]={
            0x42, 0x4d, 0x36, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
            0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        };
        FILE *fout=fopen(filename, "wb");
        fwrite(header, sizeof(header), 1, fout);
        fwrite(array, SIZE, 1, fout);
        fclose(fout);
    }
    
    #define fceA(x,y) (((x)-100)*((x)-100)+((y)-128)*((y)-128)-70*70)
    #define fceB(x,y) (((x)-40-128)*((x)-40-128)+((y)-128)*((y)-128)-70*70)
    #define max(a,b) ((a<b) ? (b) : (a))
    #define min(a,b) ((a>b) ? (b) : (a))
    
    void render(unsigned char *array)
    {
        int x, y;
        for (y=0; y<YMAX; y++) {
            for (x=0; x<XMAX; x++) {
                if (max(fceA(x,y), -fceB(x,y))<0) // !!!!!!!
                    putpixel(array, x, y, 0x00, 0xff, 0xff);
                else
                    putpixel(array, x, y, 0x00, 0x00, 0x00);
            }
        }
    }
    
    int main(void)
    {
        unsigned char* array=(unsigned char *)malloc(SIZE);
        render(array);
        save("out.bmp", array);
        free(array);
        return 0;
    }
    
    
    
  • 19. 5. 2008 15:40

    anonymní
    Děkuji za ten příklad. Tam je také čárka. :-)