// ---------------------------------------------------------------------------- // Fraktaly v pocitacove grafice // ---------------------------------------------------------------------------- // application: Morph IFS demo // author: Pavel Tisnovsky // file name: MorphIFS.java // directory: java // date: 06.07.2006 // description: Demonstracni aplikace pro vytvoreni, zobrazeni a morphovani // fraktalniho objektu, ktery je zalozeny na pruniku dvou plosnych // systemu iterovanych funkci IFS. // Podrobnejsi popis teto demonstracni aplikace je popsan primo // v 37 casti serialu o fraktalech v pocitacove grafice. // ---------------------------------------------------------------------------- // Nasledujici radky jsou urceny pro spusteni appletu v programu AppletViewer: // // <applet code="MorphIFS.class" width="640" height="700"> // </applet> // // pro kompatibilitu se starsi JVM firmy Microsoft se musi provest preklad // pomoci prikazu: // javac -target 1.1 MorphIFS.java // ---------------------------------------------------------------------------- // seznam importovanych balicku // ---------------------------------------------------------------------------- import java.util.*; import java.awt.*; import java.awt.image.*; import java.awt.event.*; import java.applet.Applet; // ---------------------------------------------------------------------------- // Trida pro aplikaci filtru na zvolenou zdrojovou pixmapu. Vysledek se uklada // do cilove pixmapy. // ---------------------------------------------------------------------------- class Filter { private int imageWidth; // velikost zpracovavanych pixmap private int imageHeight; private int pixelSrc[]; // zdrojova pixmapa private int pixelDest[]; // cilova pixmapa // ------------------------------------------------------------------------ // V konstruktoru se nastavi velikost filtru a zdrojova a cilova pixmapa. // ------------------------------------------------------------------------ public Filter(int imageWidth, int imageHeight, int pixelSrc[], int pixelDest[]) { this.imageWidth=imageWidth; // nastavit velikost pixmapy this.imageHeight=imageHeight; this.pixelSrc=pixelSrc; // nastavit handle zdrojove this.pixelDest=pixelDest; // a cilove pixmapy } // ------------------------------------------------------------------------ // Nastaveni nove sirky zpracovavane pixmapy. // ------------------------------------------------------------------------ public void setImageWidth(int imageWidth) { this.imageWidth=imageWidth; } // ------------------------------------------------------------------------ // Nastaveni nove vysky zpracovavane pixmapy. // ------------------------------------------------------------------------ public void setImageHeight(int imageHeight) { this.imageHeight=imageHeight; } // ------------------------------------------------------------------------ // Nastaveni zdrojove pixmapy. // ------------------------------------------------------------------------ public void setSourceImage(int pixelSrc[]) { this.pixelSrc=pixelSrc; } // ------------------------------------------------------------------------ // Nastaveni cilove pixmapy. // ------------------------------------------------------------------------ public void setDestinationImage(int pixelDest[]) { this.pixelDest=pixelDest; } // ------------------------------------------------------------------------ // Ziskani sirky zpracovavanych pixmap. // ------------------------------------------------------------------------ public int getImageWidth() { return imageWidth; } // ------------------------------------------------------------------------ // Ziskani vysky zpracovavanych pixmap. // ------------------------------------------------------------------------ public int getImageHeight() { return imageHeight; } // ------------------------------------------------------------------------ // Ziskani zdrojove pixmapy. // ------------------------------------------------------------------------ public int[] getSourceImage() { return pixelSrc; } // ------------------------------------------------------------------------ // Ziskani cilove pixmapy. // ------------------------------------------------------------------------ public int[] getDestinationImage() { return pixelDest; } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // zadny filtr, pouze kopie zdrojove pixmapy do cilove pixmapy. // Blizsi informace o tomto filtru jsou podany v dodatku disertacni prace. // ------------------------------------------------------------------------ public void filterNone() { int pos=0; for (int j=0; j<imageHeight; j++) { // pro vsechny radky pixmapy for (int i=0; i<imageWidth; i++) { // pro vsechny pixely na radku pixelDest[pos]=pixelSrc[pos]; // provest vymazani pixelu pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 2x2 pixely s vyberem ve tvaru bloku. // Blizsi informace o tomto filtru jsou podany v dodatku disertacni prace. // ------------------------------------------------------------------------ public void filter2x2smooth() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat for (int j=0; j<imageHeight-1; j++) { // pro vsechny radky pixmapy for (int i=0; i<imageWidth-1; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=4; g/=4; b/=4; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 3x3 pixely s vyberem ve tvaru diamantu. // Blizsi informace o tomto filtru jsou podany v dodatku disertacni prace. // ------------------------------------------------------------------------ public void filter3x3diamond() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=1+imageWidth; for (int j=1; j<imageHeight-1; j++) { // pro vsechny radky pixmapy for (int i=1; i<imageWidth-1; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-imageWidth]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=4; g/=4; b/=4; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 3x3 pixely s vyberem ve tvaru osoveho krize. // Blizsi informace o tomto filtru jsou podany v dodatku disertacni prace. // ------------------------------------------------------------------------ public void filter3x3cross() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=1+imageWidth; for (int j=1; j<imageHeight-1; j++) { // pro vsechny radky pixmapy for (int i=1; i<imageWidth-1; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-imageWidth]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=5; g/=5; b/=5; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 3x3 pixelu s vyberem ve tvaru uhlopricneho krize. // Blizsi informace o tomto filtru jsou podany v dodatku disertacni prace. // ------------------------------------------------------------------------ public void filter3x3Xcross() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=1+imageWidth; for (int j=1; j<imageHeight-1; j++) { // pro vsechny radky pixmapy for (int i=1; i<imageWidth-1; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-imageWidth-1]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos-imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=5; g/=5; b/=5; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 3x3 pixelu s blokovym vyberem. // Blizsi informace o tomto filtru jsou podany v dodatku disertacni prace. // ------------------------------------------------------------------------ public void filter3x3block() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=1+imageWidth; for (int j=1; j<imageHeight-1; j++) { // pro vsechny radky pixmapy for (int i=1; i<imageWidth-1; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-imageWidth-1]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos-imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=9; g/=9; b/=9; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 5x5 pixelu s vyberem ve tvaru diamantu. // Blizsi informace o tomto filtru jsou podany v dodatku disertacni prace. // ------------------------------------------------------------------------ public void filter5x5diamond() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=2+2*imageWidth; for (int j=2; j<imageHeight-2; j++) { // pro vsechny radky pixmapy for (int i=2; i<imageWidth-2; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-2*imageWidth+0]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos- imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=8; g/=8; b/=8; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 5x5 pixelu s vyberem ve tvaru osoveho krize. // Blizsi informace o tomto filtru jsou podany v dodatku disertacni prace. // ------------------------------------------------------------------------ public void filter5x5cross() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=2+2*imageWidth; for (int j=2; j<imageHeight-2; j++) { // pro vsechny radky pixmapy for (int i=2; i<imageWidth-2; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-2*imageWidth+0]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos- imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=9; g/=9; b/=9; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 5x5 pixelu s vyberem ve tvaru uhlopricneho krize. // Blizsi informace o tomto filtru jsou podany v dodatku disertacni prace. // ------------------------------------------------------------------------ public void filter5x5Xcross() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=2+2*imageWidth; for (int j=2; j<imageHeight-2; j++) { // pro vsechny radky pixmapy for (int i=2; i<imageWidth-2; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-2*imageWidth-2]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos-2*imageWidth+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth-2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=9; g/=9; b/=9; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 5x5 pixelu s vyberem ve tvaru bloku. // Blizsi informace o tomto filtru jsou podany v dodatku disertacni prace. // ------------------------------------------------------------------------ public void filter5x5block() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=2+2*imageWidth; for (int j=2; j<imageHeight-2; j++) { // pro vsechny radky pixmapy for (int i=2; i<imageWidth-2; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-2*imageWidth-2]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos-2*imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-2*imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-2*imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-2*imageWidth+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth-2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth-2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth-2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=25; g/=25; b/=25; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // horizontalni filtr rozmazani tri pixelu. // Blizsi informace o tomto filtru jsou podany v dodatku disertacni prace. // ------------------------------------------------------------------------ public void filter3pixelsH() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=1; for (int j=0; j<imageHeight; j++) { // pro vsechny radky pixmapy for (int i=1; i<imageWidth-1; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-1]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=3; g/=3; b/=3; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // vertikalni filtr rozmazani tri pixelu. // Blizsi informace o tomto filtru jsou podany v dodatku disertacni prace. // ------------------------------------------------------------------------ public void filter3pixelsV() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=imageWidth; for (int j=1; j<imageHeight-1; j++) { // pro vsechny radky pixmapy for (int i=0; i<imageWidth; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-imageWidth]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=3; g/=3; b/=3; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // horizontalni filtr rozmazani peti pixelu. // Blizsi informace o tomto filtru jsou podany v dodatku disertacni prace. // ------------------------------------------------------------------------ public void filter5pixelsH() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=2; for (int j=0; j<imageHeight; j++) { // pro vsechny radky pixmapy for (int i=2; i<imageWidth-2; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-2]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=5; g/=5; b/=5; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // vertikalni filtr rozmazani peti pixelu. // Blizsi informace o tomto filtru jsou podany v dodatku disertacni prace. // ------------------------------------------------------------------------ public void filter5pixelsV() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=2*imageWidth; for (int j=2; j<imageHeight-2; j++) { // pro vsechny radky pixmapy for (int i=0; i<imageWidth; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-2*imageWidth]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos- imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=5; g/=5; b/=5; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } } // ---------------------------------------------------------------------------- // Konec tridy Filter. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Trida s panelem, na kterem se zobrazuje pixmapa o predem danem rozmeru. // ---------------------------------------------------------------------------- class ImagePanel extends Canvas { int width; // rozmery pixmapy int height; public int[] pixels; // pixmapa - zdroj pixelu MemoryImageSource imageSource; // objekt zaobalujici zdroj pixelu Image image; // pixmapa vytvorena nad zdrojem pixelu // ------------------------------------------------------------------------ // V konstruktoru se nastavi velikost panelu a soucasne barva jeho pozadi. // ------------------------------------------------------------------------ public ImagePanel(int width, int height) { pixels=new int[width*height]; for (int j=0; j<height; j++) // pro vsechny radky pixmapy for (int i=0; i<width; i++) // pro vsechny sloupce pixmapy pixels[i+j*width]=0xffffffff; // vyplnit pixmapu i s alfa kanalem imageSource=new MemoryImageSource(width, height, pixels, 0, height); image=createImage(imageSource); // vytvoreni pixmapy this.width=width; // nastaveni velikosti pixmapy this.height=height; this.setBackground(Color.white); // nastaveni vlastnosti panelu this.setSize(width, height); } // ------------------------------------------------------------------------ // Pristup k jednotlivym pixelum pixmapy. // ------------------------------------------------------------------------ public void putpixel(int x, int y, int r, int g, int b) { pixels[x+y*width]=r+(g<<8)+(b<<16)+(255<<24); } // ------------------------------------------------------------------------ // Aplikaci dostupne prekresleni celeho panelu s volbou vymazu stare kresby. // ------------------------------------------------------------------------ public void redraw(boolean clear) { Graphics g=this.getGraphics(); if (clear) // premazat starou kresbu g.clearRect(0, 0, width, height); image.flush(); // prenest pixely do obrazu g.drawImage(image, 0, 0, this); // a vykreslit obraz s pixmapou } // ------------------------------------------------------------------------ // Prekresleni panelu s pixmapou. // ------------------------------------------------------------------------ public void paint(Graphics g) { g.drawImage(image, 0, 0, this); // vykreslit obraz s pixmapou } } // ---------------------------------------------------------------------------- // Konec tridy ImagePanel. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Trida s kodem pro zobrazeni napovedy. // ---------------------------------------------------------------------------- class WindowHelp extends Frame implements ActionListener { static boolean visible=false; // priznak indikujici zobrazeni napovedy // ------------------------------------------------------------------------ // Konstrukce okna s napovedou. // ------------------------------------------------------------------------ public WindowHelp() { TextArea text=new TextArea( "1. choose first IFS system\n"+ "2. choose second IFS system\n"+ "3. adjust number of points\n"+ "4. adjust start iteration\n"+ "5. adjust morph ratio between first and second IFS systems\n"+ "6. then press the 'Recalc' button\n"+ "7. apply filter with 'Redraw' button" ); visible=true; Button buttonOK=new Button("ok"); Label label=new Label("How to work with this applet:"); buttonOK.addActionListener(this); // po stlaceni tlacitka se ma napoveda zavrit this.setSize(320, 240); // nastaveni velikosti a rozmeru okna this.setLocation(100, 100); this.setTitle("Morph IFS - Help"); // zobrazeni titulku this.add("Center", text); // a pridani vsech ovladacich prvku this.add("South", buttonOK); this.add("North", label); this.setVisible(true); } // ------------------------------------------------------------------------ // Reakce na stlaceni tlacitka s textem OK. // ------------------------------------------------------------------------ public void actionPerformed(ActionEvent e) { visible=false; this.dispose(); } } // ---------------------------------------------------------------------------- // Konec tridy WindowHelp. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Trida s kodem pro zobrazeni informaci o aplikaci. // ---------------------------------------------------------------------------- class WindowAbout extends Frame implements ActionListener { static boolean visible=false; // priznak indikujici zobrazeni okna // ------------------------------------------------------------------------ // Konstrukce okna s informaci o aplikaci. // ------------------------------------------------------------------------ public WindowAbout() { TextArea text=new TextArea( "Morph IFS demo\n\n"+ "version 1.0\n"+ "Author: Pavel Tisnovsky\n"+ "Date: 2004-09-20\n"+ "http://www.fit.vutbr.cz/~tisnovpa\n" ); visible=true; Button buttonOK=new Button("ok"); Label label=new Label("About Morph IFS"); buttonOK.addActionListener(this); // po stlaceni tlacitka se ma okno zavrit this.setSize(320, 240); // nastaveni velikosti a rozmeru okna this.setLocation(100, 100); this.setTitle("Morph IFS - About"); this.add("Center", text); // a pridani vsech ovladacich prvku this.add("South", buttonOK); this.add("North", label); this.setVisible(true); } // ------------------------------------------------------------------------ // Reakce na stlaceni tlacitka s textem OK. // ------------------------------------------------------------------------ public void actionPerformed(ActionEvent e) { visible=false; this.dispose(); } } // ---------------------------------------------------------------------------- // Konec tridy WindowAbout. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Trida s kodem pro zobrazeni informaci o systemu. // ---------------------------------------------------------------------------- class WindowInfo extends Frame implements ActionListener { static boolean visible=false; // priznak indikujici zobrazeni okna // ------------------------------------------------------------------------ // Konstrukce okna s informacemi. // ------------------------------------------------------------------------ public WindowInfo() { Runtime r=Runtime.getRuntime(); // ziskat objekt s informacemi o aplikaci TextArea text=new TextArea(""); text.append("Total memory: "+r.totalMemory()+"\n"); text.append("Free memory: "+r.freeMemory()+"\n"); visible=true; Button buttonOK=new Button("ok"); Label label=new Label("System informations:"); buttonOK.addActionListener(this); // po stlaceni tlacitka se ma okno zavrit this.setSize(320, 240); // nastaveni velikosti a rozmeru okna this.setLocation(100, 100); this.setTitle("Morph IFS - Info"); // zobrazeni titulku this.add("Center", text); // a pridani vsech ovladacich prvku this.add("South", buttonOK); this.add("North", label); this.setVisible(true); } // ------------------------------------------------------------------------ // Reakce na stlaceni tlacitka s textem OK. // ------------------------------------------------------------------------ public void actionPerformed(ActionEvent e) { visible=false; this.dispose(); } } // ---------------------------------------------------------------------------- // Konec tridy WindowInfo. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Rozhrani s tvary bodu. // ---------------------------------------------------------------------------- interface PointShape { int OnePixel= 0, // bod ma tvar jednoho pixelu Cross3x3= 1, // pet pixelu ve tvaru krize XCross3x3= 2, // pet pixelu ve tvaru uhlopricneho krize Diamond3x3= 3, // ctyri pixely ve tvaru diamantu Block3x3= 4, // blok deviti pixelu Cross5x5= 5, // dtto pro okoli 5x5 XCross5x5= 6, Diamond5x5= 7, Block5x5= 8, Horizontal3=9, // tri pixely vedle sebe Horizontal5=10, // pet pixelu vedle sebe Vertical3= 11, // tri pixely pod sebou Vertical5= 12; // pet pixelu pod sebou } // ---------------------------------------------------------------------------- // Konec rozhrani PointShape. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Rozhrani se jmeny filtru. // ---------------------------------------------------------------------------- interface FilterType { int None= 0, // zadny filtr Smooth2x2= 1, // filtr typu 2x2 smooth Diamond3x3= 2, // filtr typu 3x3 diamond Cross3x3= 3, // filtr typu 3x3 cross XCross3x3= 4, // filtr typu 3x3 X cross Block3x3= 5, // filtr typu 3x3 block Diamond5x5= 6, // filtr typu 5x5 diamond Cross5x5= 7, // filtr typu 5x5 cross XCross5x5= 8, // filtr typu 5x5 X cross Block5x5= 9, // filtr typu 5x5 block Horizontal3=10, // filtr typu 3 pixels horizontal Horizontal5=11, // filtr typu 5 pixels horizontal Vertical3= 12, // filtr typu 3 pixels vertical Vertical5= 13; // filtr typu 5 pixels vertical } // ---------------------------------------------------------------------------- // Konec rozhrani FilterType. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Rozhrani se jmeny IFS systemu. // ---------------------------------------------------------------------------- interface IFStype { int Binary= 0, // nazvy jednotlivych fraktalu Coral= 1, // jsou prevzaty z programu Crystal= 2, // FractInt/WinFractInt Dragon= 3, Dragon2= 4, Feathe= 5, Fern= 6, Ferny= 7, Flake= 8, Floor= 9, Fossil= 10, Koch= 11, Leaf= 12, Leaf2= 13, Pincher= 14, Pull= 15, Spiral= 16, Spiral2= 17, Swirl= 18, Square= 19, Telephon= 20, Tree= 21, Tree2= 22, Tree3= 23, Triangle= 24, Z= 25, Zigzag= 26; } // ---------------------------------------------------------------------------- // Konec rozhrani IFStype. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // V pripade, ze by bylo nutne tento demonstrani program spustit jako Java ap- // likaci, je mozne odkomentovat metodu "main". V tomto pripade se vsak vytvo- // ri dalsi soubor .class s anonymni tridou Listener. // ---------------------------------------------------------------------------- public class MorphIFS extends Applet implements Runnable, ActionListener, ItemListener, AdjustmentListener, FilterType, PointShape { static final int ImageWidth=256; // sirka pixmapy s fraktalem static final int ImageHeight=256; // vyska pixmapy s fraktalem static final int DrawingWidth=256; // sirka kresby pouzivane pro konstrukci fraktalu static final int DrawingHeight=256+150; // vyska kresby pouzivane pro konstrukci fraktalu static final int TextBegin=256+10; // horizontalni zacatek informacniho textu static final int TextHeight=120; // vyska informacniho textu int maxIter=5000; // pocet vsech iteraci int startIter=200; // pocet startovnich iteraci double morphRatio=0.0; // morfovani dvou objektu int pointShape=PointShape.OnePixel;// typ vykreslovanych bodu int filterType=FilterType.Cross3x3;// typ pouziteho filtru int firstIFS=IFStype.Fern; // prvni IFS system int secondIFS=IFStype.Tree; // druhy IFS system static int putpixelMode=0; // vykreslovaci rezim // vytvoreni vsech panelu pouzitych v appletu ImagePanel morphIfs= new ImagePanel(ImageWidth, ImageHeight); ImagePanel filteredIfs= new ImagePanel(ImageWidth, ImageHeight); ImagePanel Ifs1= new ImagePanel(ImageWidth, ImageHeight); ImagePanel Ifs2= new ImagePanel(ImageWidth, ImageHeight); Panel panelLeft= new Panel(new GridLayout(2, 2, 5, 5)); Panel panelUp= new Panel(new GridLayout(2, 5, 5, 5));// horni panel s list-boxy Panel panelDown= new Panel(new GridLayout(2, 3, 5, 5));// dolni panel s posuvniky Panel panelRight= new Panel(new GridLayout(8, 1));// pravy panel s tlacitky // filtr aplikovany na zdrojovou pixmapu, vysledek je v cilove pixmape Filter filter=new Filter(ImageWidth, ImageHeight, morphIfs.pixels, filteredIfs.pixels); IFS ifs=null; // vytvoreni vsech textovych navesti pouzitych v appletu Label labelFirstIFS= new Label("First system"); Label labelSecondIFS= new Label("Second system"); Label labelPointShape= new Label("Point shape"); Label labelFilterType= new Label("Filter"); Label labelPutpixelMode= new Label("Putpixel mode"); Label labelMaxIter= new Label("Iterations: "+String.valueOf(maxIter)); Label labelStartIter= new Label("Start iterations: "+String.valueOf(startIter)); Label labelMorph= new Label("Morph ratio: "+String.valueOf(morphRatio)); // vytvoreni vsech list-boxu pouzitych v appletu Choice choicePointShape= new Choice(); // list-box pro vyber tvaru bodu Choice choiceFilter= new Choice(); // list-box pro vyber aktivniho filtru Choice choiceFirstIFS= new Choice(); Choice choiceSecondIFS= new Choice(); Choice choicePutpixelMode= new Choice(); // list-box pro vyber vykreslovaciho rezimu // vytvoreni vsech tlacitek pouzitych v appletu Button buttonRedraw= new Button("Redraw"); Button buttonRecalc= new Button("Recalc"); Button buttonAbout= new Button("About"); Button buttonInfo= new Button("Info"); Button buttonHelp= new Button("Help"); // vytvoreni vsech slideru pouzitych v appletu Scrollbar scrollBarMaxIter= new Scrollbar(Scrollbar.HORIZONTAL, maxIter, 10000, 2000, 100000+10000); Scrollbar scrollBarStartIter= new Scrollbar(Scrollbar.HORIZONTAL, startIter, 100, 200, 1000+100); Scrollbar scrollBarMorphRatio= new Scrollbar(Scrollbar.HORIZONTAL, (int)morphRatio*1000, 100, 0, 1000+100); // ------------------------------------------------------------------------ // Tato metoda provede inicializaci horniho panelu s rolovacimi list-boxy. // Metoda je zavolana behem inicializace aplikace ci appletu. // ------------------------------------------------------------------------ private void initPanelUp() { panelUp.setBackground(Color.white); // nastaveni barvy pozadi panelUp.add(labelFirstIFS); // pridani vsech textovych navesti panelUp.add(labelSecondIFS); // do horniho panelu panelUp.add(labelPointShape); panelUp.add(labelFilterType); panelUp.add(labelPutpixelMode); panelUp.add(choiceFirstIFS); panelUp.add(choiceSecondIFS); panelUp.add(choicePointShape); // pridani vsech list-boxu panelUp.add(choiceFilter); panelUp.add(choicePutpixelMode); // prace s list-boxem pointShape choicePointShape.setEnabled(true); // naplneni list-boxu texty a povoleni list-boxu choicePointShape.add("1 pixel"); choicePointShape.add("Cross 3x3 pixels"); choicePointShape.add("X cross 3x3 pixels"); choicePointShape.add("Diamond 3x3 pixels"); choicePointShape.add("Block 3x3 pixels"); choicePointShape.add("Cross 5x5 pixels"); choicePointShape.add("X cross 3x3 pixels"); choicePointShape.add("Diamond 5x5 pixels"); choicePointShape.add("Block 5x5 pixels"); choicePointShape.add("3 pixels horizontal"); choicePointShape.add("5 pixels horizontal"); choicePointShape.add("3 pixels vertical"); choicePointShape.add("5 pixels vertical"); choicePointShape.select(pointShape); // vyber aktivni polozky z list-boxu choicePointShape.addItemListener(this); // nastaveni zpracovani udalosti od list-boxu // prace s list-boxem Filter choiceFilter.setEnabled(true); // naplneni list-boxu texty a povoleni list-boxu choiceFilter.add("none"); choiceFilter.add("2x2 smooth"); choiceFilter.add("3x3 diamond"); choiceFilter.add("3x3 cross"); choiceFilter.add("3x3 X cross"); choiceFilter.add("3x3 block"); choiceFilter.add("5x5 diamond"); choiceFilter.add("5x5 cross"); choiceFilter.add("5x5 X cross"); choiceFilter.add("5x5 block"); choiceFilter.add("3 pixels horizontal"); choiceFilter.add("5 pixels horizontal"); choiceFilter.add("3 pixels vertical"); choiceFilter.add("5 pixels vertical"); choiceFilter.select(filterType); // vyber aktivni polozky z list-boxu choiceFilter.addItemListener(this); // nastaveni zpracovani udalosti od list-boxu // prace s list-boxem FirstIFS choiceFirstIFS.setEnabled(true); // naplneni list-boxu texty a povoleni list-boxu choiceFirstIFS.add("Binary"); choiceFirstIFS.add("Coral"); choiceFirstIFS.add("Crystal"); choiceFirstIFS.add("Dragon 1"); choiceFirstIFS.add("Dragon 2"); choiceFirstIFS.add("Feathe"); choiceFirstIFS.add("Fern"); choiceFirstIFS.add("Ferny"); choiceFirstIFS.add("Flake"); choiceFirstIFS.add("Floor"); choiceFirstIFS.add("Fossil"); choiceFirstIFS.add("Koch"); choiceFirstIFS.add("Leaf 1"); choiceFirstIFS.add("Leaf 2"); choiceFirstIFS.add("Pincher"); choiceFirstIFS.add("Pull"); choiceFirstIFS.add("Spiral 1"); choiceFirstIFS.add("Spiral 2"); choiceFirstIFS.add("Swirl"); choiceFirstIFS.add("Square"); choiceFirstIFS.add("Telephon"); choiceFirstIFS.add("Tree 1"); choiceFirstIFS.add("Tree 2"); choiceFirstIFS.add("Tree 3"); choiceFirstIFS.add("Triangle"); choiceFirstIFS.add("Z"); choiceFirstIFS.add("Zig-zag"); choiceFirstIFS.select(firstIFS); // vyber aktivni polozky z list-boxu choiceFirstIFS.addItemListener(this); // nastaveni zpracovani udalosti od list-boxu // prace s list-boxem SecondIFS choiceSecondIFS.setEnabled(true); // naplneni list-boxu texty a povoleni list-boxu choiceSecondIFS.add("Binary"); choiceSecondIFS.add("Coral"); choiceSecondIFS.add("Crystal"); choiceSecondIFS.add("Dragon"); choiceSecondIFS.add("Dragon 2"); choiceSecondIFS.add("Feathe"); choiceSecondIFS.add("Fern"); choiceSecondIFS.add("Ferny"); choiceSecondIFS.add("Flake"); choiceSecondIFS.add("Floor"); choiceSecondIFS.add("Fossil"); choiceSecondIFS.add("Koch"); choiceSecondIFS.add("Leaf 1"); choiceSecondIFS.add("Leaf 2"); choiceSecondIFS.add("Pincher"); choiceSecondIFS.add("Pull"); choiceSecondIFS.add("Spiral 1"); choiceSecondIFS.add("Spiral 2"); choiceSecondIFS.add("Swirl"); choiceSecondIFS.add("Square"); choiceSecondIFS.add("Telephon"); choiceSecondIFS.add("Tree 1"); choiceSecondIFS.add("Tree 2"); choiceSecondIFS.add("Tree 3"); choiceSecondIFS.add("Triangle"); choiceSecondIFS.add("Z"); choiceSecondIFS.add("Zig-zag"); choiceSecondIFS.select(secondIFS); // vyber aktivni polozky z list-boxu choiceSecondIFS.addItemListener(this); // nastaveni zpracovani udalosti od list-boxu // prace s list-boxem putpixel mode choicePutpixelMode.setEnabled(true); choicePutpixelMode.add("draw black pixel"); choicePutpixelMode.add("add 4"); choicePutpixelMode.add("add 8"); choicePutpixelMode.add("add 12"); choicePutpixelMode.add("add 16"); choicePutpixelMode.add("add 20"); choicePutpixelMode.select(putpixelMode); choicePutpixelMode.addItemListener(this); } // ------------------------------------------------------------------------ // Tato metoda provede inicializaci dolniho panelu se slidery. // Metoda je zavolana behem inicializace aplikace ci appletu. // ------------------------------------------------------------------------ private void initPanelDown() { panelDown.setBackground(Color.white); // nastaveni barvy pozadi panelDown.add(labelMaxIter); // pridani vsech textovych navesti panelDown.add(labelStartIter); panelDown.add(labelMorph); panelDown.add(scrollBarMaxIter); // pridani vsech slideru panelDown.add(scrollBarStartIter); panelDown.add(scrollBarMorphRatio); scrollBarMaxIter.addAdjustmentListener(this);// nastaveni reakci na udalosti slideru scrollBarStartIter.addAdjustmentListener(this); scrollBarMorphRatio.addAdjustmentListener(this); } // ------------------------------------------------------------------------ // Tato metoda provede nastaveni praveho panelu s tlacitky (buttony). // Metoda je zavolana behem inicializace aplikace ci appletu. // ------------------------------------------------------------------------ private void initPanelRight() { panelRight.setBackground(Color.white); // nastaveni barvy pozadi panelRight.add(buttonRecalc); // pridani vsech textovych tlacitek panelRight.add(buttonRedraw); panelRight.add(new Label("")); // volna polozka pro oddeleni tlacitek panelRight.add(buttonAbout); panelRight.add(buttonInfo); panelRight.add(buttonHelp); buttonRedraw.addActionListener(this); // nastaveni reakce na udalosti od tlacitek buttonRecalc.addActionListener(this); buttonAbout.addActionListener(this); buttonInfo.addActionListener(this); buttonHelp.addActionListener(this); } // ------------------------------------------------------------------------ // Tato metoda provede nastaveni leveho panelu s obrazky. // ------------------------------------------------------------------------ private void initPanelLeft() { panelLeft.setBackground(Color.white); panelLeft.add(Ifs1); panelLeft.add(Ifs2); panelLeft.add(morphIfs); panelLeft.add(filteredIfs); } // ------------------------------------------------------------------------ // Tato metoda provede inicializaci appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void init() { this.setBackground(Color.white); // nastaveni barvy pozadi setLayout(new BorderLayout(5,5)); // nastaveni layoutu aplikace initPanelUp(); // nastavit horni panel initPanelDown(); // nastavit dolni panel initPanelRight(); // nastavit pravy panel initPanelLeft(); // nastavit levy panel add("North", panelUp); // pridat horni panel do plochy aplikace add("South", panelDown); // pridat dolni panel do plochy aplikace add("East", panelRight); // pridat pravy panel do plochy aplikace add("West", panelLeft); } // ------------------------------------------------------------------------ // Tato metoda se zavola pri destrukci appletu. // Metoda je volana z virtualniho stroje Javy (JVM) // ------------------------------------------------------------------------ public void destroy() { remove(panelLeft); remove(panelRight); // zrusit pravy panel remove(panelUp); // zrusit horni panel remove(panelDown); // zrusit dolni panel remove(filteredIfs); // zrusit centralni panel } // ------------------------------------------------------------------------ // Tato metoda se zavola vzdy pri nastartovani appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void start() { recalcFractal(true); } // ------------------------------------------------------------------------ // Tato metoda se zavola pri kazdem zastaveni appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void stop() { } // ------------------------------------------------------------------------ // Tato metoda se zavola pri nastartovani appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void run() { repaint(); // prvotni vykresleni plochy appletu } // ------------------------------------------------------------------------ // Tato metoda se zavola vzdy, kdyz je nutno prekreslit plochu appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void update(Graphics g) { paint(g); // povolit prekresleni appletu } // ------------------------------------------------------------------------ // Tato metoda se zavola kdyz je potreba prekreslit applet. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void paint(Graphics g) { } // ------------------------------------------------------------------------ // Nastaveni vnitrnich okraju v okne appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public Insets getInsets() { return new Insets(5, 5, 5, 5); } // ------------------------------------------------------------------------ // Tato metoda je zavolana v pripade, ze je stlaceno nektere tlacitko // umistene na plose appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void actionPerformed(ActionEvent e) { Object o=e.getSource(); // ktere tlacitko je stlaceno? if (o==buttonRedraw) { // ma se pouze prekreslit fraktal morphIfs.redraw(false); applyFilter(); filteredIfs.redraw(false); } if (o==buttonRecalc) { // prepocitani celeho fraktalu recalcFractal(true); } if (o==buttonAbout) { // text s informacemi o autorech if (!WindowAbout.visible) { WindowAbout window=new WindowAbout(); } } if (o==buttonHelp) { // text s napovedou if (!WindowHelp.visible) { WindowHelp window=new WindowHelp(); } } if (o==buttonInfo) { // text s informacemi o aplikaci if (!WindowInfo.visible) { WindowInfo window=new WindowInfo(); } } } // ------------------------------------------------------------------------ // Tato metoda je zavolana v pripade, ze je vybran prvek z list-boxu // umisteneho na plose appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void itemStateChanged(ItemEvent e) { Object o=e.getSource(); // ziskat informace, ktery list-box je zmenen if (o==choicePointShape) { pointShape=choicePointShape.getSelectedIndex(); recalcFractal(true); } if (o==choiceFilter) { // uzivatel zmenil filtr aplikovany na obrazek filterType=choiceFilter.getSelectedIndex();// ziskat index vybraneho filtru applyFilter(); filteredIfs.redraw(false); } if (o==choiceFirstIFS) { firstIFS=choiceFirstIFS.getSelectedIndex(); recalcFractal(true); } if (o==choiceSecondIFS) { secondIFS=choiceSecondIFS.getSelectedIndex(); recalcFractal(true); } if (o==choicePutpixelMode) { putpixelMode=choicePutpixelMode.getSelectedIndex(); recalcFractal(true); } } // ------------------------------------------------------------------------ // Tato metoda je zavolana v pripade, ze uzivatel zmenil polohu nektereho // posuvniku (slideru) umisteneho na plose appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void adjustmentValueChanged(AdjustmentEvent e) { Object o=e.getSource(); // ziskat slider, ktery byl zmenen if (o==scrollBarMaxIter) { // zmena poctu iteraci maxIter=scrollBarMaxIter.getValue(); // ziskat pocet iteraci labelMaxIter.setText("Iterations: "+String.valueOf(maxIter)); } if (o==scrollBarStartIter) { // zmena poctu startovnich iteraci startIter=scrollBarStartIter.getValue();// ziskat pocet startovnich teraci labelStartIter.setText("Start iterations: "+String.valueOf(startIter)); } if (o==scrollBarMorphRatio) { // uroven morphingu mezi objekty morphRatio=scrollBarMorphRatio.getValue()/1000.0;// ziskat uroven morphingu labelMorph.setText("Morph ratio: "+String.valueOf(morphRatio)); recalcFractal(false); } } // ------------------------------------------------------------------------ // Tato metoda zmeni aktualni filtr. // ------------------------------------------------------------------------ public void applyFilter() { switch (filterType) { case FilterType.None: filter.filterNone(); break; // zadny filtr case FilterType.Smooth2x2: filter.filter2x2smooth(); break; // filtr typu 2x2 smooth case FilterType.Diamond3x3: filter.filter3x3diamond(); break; // filtr typu 3x3 diamond case FilterType.Cross3x3: filter.filter3x3cross(); break; // filtr typu 3x3 cross case FilterType.XCross3x3: filter.filter3x3Xcross(); break; // filtr typu 3x3 X cross case FilterType.Block3x3: filter.filter3x3block(); break; // filtr typu 3x3 block case FilterType.Diamond5x5: filter.filter5x5diamond(); break; // filtr typu 5x5 diamond case FilterType.Cross5x5: filter.filter5x5cross(); break; // filtr typu 5x5 cross case FilterType.XCross5x5: filter.filter5x5Xcross(); break; // filtr typu 5x5 X cross case FilterType.Block5x5: filter.filter5x5block(); break; // filtr typu 5x5 block case FilterType.Horizontal3:filter.filter3pixelsH(); break; // filtr typu 3 pixels horizontal case FilterType.Horizontal5:filter.filter5pixelsH(); break; // filtr typu 5 pixels horizontal case FilterType.Vertical3: filter.filter3pixelsV(); break; // filtr typu 3 pixels vertical case FilterType.Vertical5: filter.filter5pixelsV(); break; // filtr typu 5 pixels vertical default: break; // tato volba by nemela nikdy nastat } } // ------------------------------------------------------------------------ // Tato metoda provede prepocet fraktalu. // ------------------------------------------------------------------------ private void recalcFractal(boolean bfilter) { if (ifs!=null) { if (ifs.isAlive()) return; } ifs=new IFS(); // vytvorit novy generator fraktalu ifs.setPixels(morphIfs.pixels); // nastavit jeho parametry ifs.setSize(ImageWidth, ImageHeight); ifs.setMaxIter(maxIter); ifs.setStartIter(startIter); ifs.setPointShape(pointShape); ifs.setMorphRatio(morphRatio); ifs.setFirstIFS(firstIFS); ifs.setSecondIFS(secondIFS); ifs.setObject(this); ifs.setFilter(bfilter); ifs.setPutpixelMode(putpixelMode); ifs.start(); // a spustit ho if (bfilter) { IFS ifs1=new IFS(); ifs1.setPixels(Ifs1.pixels); ifs1.setSize(ImageWidth, ImageHeight); ifs1.setMaxIter(maxIter); ifs1.setStartIter(startIter); ifs1.setPointShape(pointShape); ifs1.setMorphRatio(0.0f); ifs1.setFirstIFS(firstIFS); ifs1.setSecondIFS(firstIFS); ifs1.setObject(this); ifs1.setFilter(false); ifs1.setPutpixelMode(putpixelMode); ifs1.runInSingleThread(); Ifs1.redraw(false); IFS ifs2=new IFS(); ifs2.setPixels(Ifs2.pixels); ifs2.setSize(ImageWidth, ImageHeight); ifs2.setMaxIter(maxIter); ifs2.setStartIter(startIter); ifs2.setPointShape(pointShape); ifs2.setMorphRatio(0.0f); ifs2.setFirstIFS(secondIFS); ifs2.setSecondIFS(secondIFS); ifs2.setObject(this); ifs2.setFilter(false); ifs2.setPutpixelMode(putpixelMode); ifs2.runInSingleThread(); Ifs2.redraw(false); } } /* // ----------------------------------------------------------------------- // Metoda main, ktera neni v appletu vyuzita. // Muze se definovat v pripade, ze se ma vytvorit samostatne spustitelna // aplikace interpretovana virtualnim strojem jazyja Java, nikoli applet. // ----------------------------------------------------------------------- public static void main(String[] args) { Frame frame=new Frame("Morph IFS demo"); Applet applet=new MorphIFS(); frame.add(applet); applet.init(); frame.setSize(640, 480); frame.setVisible(true); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); } */ } // ---------------------------------------------------------------------------- // Konec tridy MorphIFS. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Trida, ve krere je implementovan algoritmus generovani IFS fraktalu. // ---------------------------------------------------------------------------- class IFS extends Thread { Frame frame=null; // okno pro vypis prubehu prace Label label=null; // do tohoto labelu se bude provadet vypis int pixelSrc[]; // pixmapa pro vykreslovani int width; // velikost pixmapy int height; int maxIter; int startIter; int pointShape; // typ vykreslovych bodu int firstIFS; int secondIFS; int putpixelMode; boolean bfilter; double morphRatio; // pomer mezi prvnim a druhym IFS systemem MorphIFS object; // objekt s panely, do kterych se kresli static final double data[][]={ // binary { 0.500000, 0.000000, 0.000000, 0.500000,-2.563477,-0.000003, 0.333333}, { 0.500000, 0.000000, 0.000000, 0.500000, 2.436544,-0.000003, 0.333333}, { 0.000000,-0.500000, 0.500000, 0.000000, 4.873085, 7.563492, 0.333333}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // coral { 0.307692,-0.531469,-0.461538,-0.293706, 5.401953, 8.655175, 0.400000}, { 0.307692,-0.076923, 0.153846,-0.447552,-1.295248, 4.152990, 0.150000}, { 0.000000, 0.545455, 0.692308,-0.195804,-4.893637, 7.269794, 0.450000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // crystal { 0.696970,-0.481061,-0.393939,-0.662879, 2.147003,10.310288, 0.747826}, { 0.090909,-0.443182, 0.515152,-0.094697, 4.286558, 2.925762, 0.252174}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // dragon { 0.824074, 0.281482,-0.212346, 0.864198,-1.882290,-0.110607, 0.787473}, { 0.088272, 0.520988,-0.463889,-0.377778, 0.785360, 8.095795, 0.212527}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // dragon2 { 0.824074, 0.281481,-0.212346, 0.864197,-1.772710, 0.137795, 0.771268}, {-0.138580, 0.283951,-0.670062,-0.279012, 2.930991, 7.338924, 0.228732}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // feathe { 0.870370, 0.074074,-0.115741, 0.851852,-1.278016, 0.070331, 0.798030}, {-0.162037,-0.407407, 0.495370, 0.074074, 6.835726, 5.799174, 0.201970}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // fern { 0.850000, 0.040000,-0.040000, 0.850000, 0.000000, 1.600000, 0.850000}, { 0.200000,-0.260000, 0.230000, 0.220000, 0.000000, 1.600000, 0.070000}, {-0.150000, 0.280000, 0.260000, 0.240000, 0.000000, 0.440000, 0.070000}, { 0.000000, 0.000000, 0.000000, 0.160000, 0.000000, 0.000000, 0.010000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // ferny {-0.160000,-0.640000, 0.433846,-0.110769, 5.264632, 8.111285, 0.321070}, { 0.603077, 0.335385,-0.280000, 0.880000,-2.757524,-0.799133, 0.678930}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // flake {-0.250000, 0.750000, 0.250000, 0.250000,-3.412025, 5.797619, 0.333333}, {-0.250000, 0.750000, 0.250000, 0.250000,-6.939442, 2.270202, 0.333333}, {-0.250000, 0.750000, 0.250000, 0.250000, 0.115392, 2.270202, 0.333333}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // floor { 0.000000,-0.500000, 0.500000 ,0.000000,-1.732366, 3.366182, 0.333333}, { 0.500000, 0.000000, 0.000000 ,0.500000,-0.027891, 5.014877, 0.333333}, { 0.000000, 0.500000,-0.500000 ,0.000000, 1.620804, 3.310401, 0.333333}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // fossil {-0.017641, 0.637128, 0.352000, 0.008000,-2.464790, 8.587118, 0.264315}, { 0.603077, 0.335385,-0.280000, 0.880000,-1.759852,-0.659994, 0.735685}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // koch { 0.307692, 0.000000, 0.000000, 0.294118, 4.119164, 1.604278, 0.151515}, { 0.192308,-0.205882, 0.653846, 0.088235,-0.688840, 5.978916, 0.253788}, { 0.192308, 0.205882,-0.653846, 0.088235, 0.668580, 5.962514, 0.253788}, { 0.307692, 0.000000, 0.000000, 0.294118,-4.136530, 1.604278, 0.151515}, { 0.384615, 0.000000, 0.000000,-0.294118,-0.007718, 2.941176, 1.000000}, // leaf { 0.242424,-0.640152,-0.909091,-0.318182, 4.613705, 5.570360, 0.698795}, {-0.090909,-0.556818,-0.484848, 0.155303,-1.103621, 5.655663, 0.301205}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // leaf2 { 0.424242,-0.651515,-0.484848,-0.344697, 3.449256, 2.891322, 0.622449}, { 0.030303,-0.439394,-0.636364,-0.022727,-1.396520, 6.437606, 0.377551}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // pincher { 0.771144,-0.484577,-0.418906,-0.724378, 2.136904, 7.581400, 0.868575}, {-0.259304,-0.109453,-0.136119, 0.171144, 5.871343, 0.808450, 0.067604}, { 0.308657, 0.125373, 0.265075,-0.073632,-5.649287, 8.277147, 0.063821}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // pull { 0.227195,-0.466437, 0.688468, 0.647160, 0.187642, 1.466229, 0.572632}, { 0.450947,-0.456110, 0.325301, 0.445783, 4.939965, 4.050190, 0.427368}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // spiral { 0.787879,-0.424242, 0.242424, 0.859848, 1.758647, 1.408065, 0.895652}, {-0.121212, 0.257576, 0.151515, 0.053030,-6.721654, 1.377236, 0.052174}, { 0.181818,-0.136364, 0.090909, 0.181818, 6.086107, 1.568035, 0.052174}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // spiral2 { 0.826500,-0.475000, 0.475000, 0.826500, 0.000000, 0.000000, 0.400000}, { 0.500000, 0.000000, 0.000000, 0.500000,-1.000000, 0.000000, 0.200000}, { 0.500000, 0.000000, 0.000000, 0.500000, 1.000000, 0.000000, 0.200000}, { 0.500000, 0.000000, 0.000000, 0.500000, 0.000000, 1.000000, 0.200000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // swirl { 0.745455,-0.459091, 0.406061, 0.887121, 1.460279, 0.691072, 0.912675}, {-0.424242,-0.065152,-0.175758,-0.218182, 3.809567, 6.741476, 0.087325}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // square { 0.500000, 0.000000, 0.000000, 0.500000,-1.000000, 0.000000, 0.250000}, { 0.500000, 0.000000, 0.000000, 0.500000, 1.000000, 0.000000, 0.250000}, { 0.500000, 0.000000, 0.000000, 0.500000, 0.000000,-1.000000, 0.250000}, { 0.500000, 0.000000, 0.000000, 0.500000, 0.000000, 1.000000, 0.250000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // telephon { 0.824074, 0.281481,-0.212346, 0.864198,-2.274768,-0.147052, 0.876993}, {-0.072222, 0.422222, 0.246296, 0.059259, 3.631163, 7.337541, 0.123007}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // tree { 0.000000, 0.000000, 0.000000, 0.500000, 0.000000, 0.000000, 0.050000}, { 0.420000,-0.420000, 0.420000, 0.420000, 0.000000, 0.200000, 0.400000}, { 0.420000, 0.420000,-0.420000, 0.420000, 0.000000, 0.200000, 0.400000}, { 0.100000, 0.000000, 0.000000, 0.100000, 0.000000, 0.200000, 0.150000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // tree 2 { 0.000000, 0.000000, 0.000000, 0.600000, 0.013606,-0.454544, 0.443441}, { 0.363636, 0.581818,-0.454545, 0.472727,-0.114619, 3.329175, 0.278280}, {-0.363636,-0.581818,-0.454545, 0.472727, 0.141832, 3.329175, 0.278280}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // tree 3 { 0.000000, 0.000000, 0.000000, 0.600000,-0.159095, 0.670061, 0.445008}, { 0.363636, 0.481818,-0.454545, 0.386061,-0.908361, 4.762463, 0.190237}, {-0.363636,-0.481818,-0.454545, 0.392727, 0.590171, 4.708041, 0.191520}, {-0.545455, 0.027273, 0.000000,-0.600000,-0.291561, 5.924281, 0.173235}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // triangle { 0.500000, 0.000000, 0.000000, 0.500000,-0.500000, 0.000000, 0.333333}, { 0.500000, 0.000000, 0.000000, 0.500000, 0.500000, 0.000000, 0.333333}, { 0.500000, 0.000000, 0.000000, 0.500000, 0.000000, 0.860000, 0.333334}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // z {-0.548060,-0.181095, 0.257313,-1.015920, 0.818014, 10.578471, 0.844961}, {-0.135124,-0.432836, 0.147065,-0.348259, 2.110459, 3.261798, 0.155039}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, // zigzag {-0.632407,-0.614815,-0.545370, 0.659259, 3.840822, 1.282321, 0.888128}, {-0.036111, 0.444444, 0.210185, 0.037037, 2.071081, 8.330552, 0.111872}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, { 1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 1.000000}, }; // ----------------------------------------------------------------------- // Konstruktor, ve kterem se nastavi vhodne implicitni hodnoty. // ----------------------------------------------------------------------- public IFS() { pixelSrc=null; width=height=100; maxIter=1000; startIter=100; pointShape=0; bfilter=false; } // ----------------------------------------------------------------------- // Nastaveni pixmapy, do ktere se bude provadet vykreslovani // ----------------------------------------------------------------------- public void setPixels(int pixels[]) { pixelSrc=pixels; } // ----------------------------------------------------------------------- // Nastaveni rozmeru generovane pixmapy. // ----------------------------------------------------------------------- public void setSize(int width, int height) { this.width=width; this.height=height; } // ----------------------------------------------------------------------- // Nastaveni maximalniho poctu bodu v pixmape. // ----------------------------------------------------------------------- public void setMaxIter(int maxIter) { this.maxIter=maxIter; } // ----------------------------------------------------------------------- // Nastaveni startovniho poctu iteraci. // ----------------------------------------------------------------------- public void setStartIter(int startIter) { this.startIter=startIter; } // ----------------------------------------------------------------------- // Nastaveni tvaru, ktery se bude ukladat do pracovni bitmapy. // ----------------------------------------------------------------------- public void setPointShape(int pointShape) { this.pointShape=pointShape; } // ----------------------------------------------------------------------- // Nastaveni urovne morfovani prvniho objektu do objektu druheho. // ----------------------------------------------------------------------- public void setMorphRatio(double morphRatio) { this.morphRatio=morphRatio; } // ----------------------------------------------------------------------- // Predani reference hlavniho GUI objektu. // ----------------------------------------------------------------------- public void setObject(MorphIFS o) { object=o; } // ----------------------------------------------------------------------- // Predani cisla prvniho IFS systemu. // ----------------------------------------------------------------------- public void setFirstIFS(int firstIFS) { this.firstIFS=firstIFS; } // ----------------------------------------------------------------------- // Predani cisla druheho IFS systemu. // ----------------------------------------------------------------------- public void setSecondIFS(int secondIFS) { this.secondIFS=secondIFS; } // ----------------------------------------------------------------------- // Povoleni ci zakazani filtrace. // ----------------------------------------------------------------------- public void setFilter(boolean bfilter) { this.bfilter=bfilter; } // ----------------------------------------------------------------------- // Nastaveni zpusobu vykresleni pixelu // ----------------------------------------------------------------------- public void setPutpixelMode(int putpixelMode) { this.putpixelMode=putpixelMode; } // ----------------------------------------------------------------------- // Vytvoreni a zobrazeni pomocneho okna, ve kterem se zobrazuje prubeh prace. // ----------------------------------------------------------------------- private void prepareGUI() { frame=new Frame("Computing IFS"); label=new Label("Points:"); frame.add(label); label.setAlignment(Label.CENTER); // vlastnosti napisu label.setVisible(true); frame.setSize(200, 100); // vlastnosti okna frame.setVisible(true); } // ----------------------------------------------------------------------- // Tato metoda se zavola po dokonceni generovani fraktalu. // ----------------------------------------------------------------------- private void finishGUI() { if (bfilter) label.setText("Filtering bitmaps"); object.morphIfs.redraw(false); if (bfilter) { object.applyFilter(); // aplikace filtru na bitmapu object.filteredIfs.redraw(false); } frame.setVisible(false); // a zruseni pomocneho okna frame.dispose(); } // ----------------------------------------------------------------------- // Vytvoreni a inicializace pixmapy. // ----------------------------------------------------------------------- private void initPixmap() { for (int p=0; p<width*height; p++) { pixelSrc[p]=0xffffffff; } } // ----------------------------------------------------------------------- // Vykresleni jednoho pixelu podle nastaveneho rezimu // ----------------------------------------------------------------------- private void putPixel(int x, int y) { switch (putpixelMode) { case 0: pixelSrc[x+y*width]=0xff000000; break; case 1: if (pixelSrc[x+y*width]>0xff040404) pixelSrc[x+y*width]-=0x00040404; break; case 2: if (pixelSrc[x+y*width]>0xff080808) pixelSrc[x+y*width]-=0x00080808; break; case 3: if (pixelSrc[x+y*width]>0xff0c0c0c) pixelSrc[x+y*width]-=0x000c0c0c; break; case 4: if (pixelSrc[x+y*width]>0xff101010) pixelSrc[x+y*width]-=0x00101010; break; case 5: if (pixelSrc[x+y*width]>0xff141414) pixelSrc[x+y*width]-=0x00141414; break; default: break; } } // ----------------------------------------------------------------------- // Vykresleni jednoho bodu do pixmapy // ----------------------------------------------------------------------- private void putPoint(int x, int y) { if (x<4) x=4; if (x>=width-3) x=width-4; if (y<4) y=4; if (y>=height-3) y=height-4; y=height-1-y; if (pointShape!=PointShape.Diamond3x3 && pointShape!=PointShape.Diamond5x5) { putPixel(x, y); // prostredni pixel } if (pointShape==PointShape.Cross3x3 || pointShape==PointShape.Diamond3x3 || pointShape==PointShape.Block3x3 || pointShape==PointShape.Cross5x5 || pointShape==PointShape.Block5x5 || pointShape==PointShape.Horizontal3 || pointShape==PointShape.Horizontal5) { putPixel(x-1,y); // pixel nalevo putPixel(x+1,y); // pixel napravo } if (pointShape==PointShape.Horizontal5 || pointShape==PointShape.Cross5x5 || pointShape==PointShape.Diamond5x5 || pointShape==PointShape.Block5x5) { putPixel(x-2,y); // druhy pixel nalevo putPixel(x+2,y); // druhy pixel napravo } if (pointShape==PointShape.Cross3x3 || pointShape==PointShape.Diamond3x3 || pointShape==PointShape.Block3x3 || pointShape==PointShape.Cross5x5 || pointShape==PointShape.Block5x5 || pointShape==PointShape.Vertical3 || pointShape==PointShape.Vertical5) { putPixel(x, y-1); // pixel nahore putPixel(x, y+1); // pixel dole } if (pointShape==PointShape.Vertical5 || pointShape==PointShape.Cross5x5 || pointShape==PointShape.Diamond5x5 || pointShape==PointShape.Block5x5) { putPixel(x, y-2); // druhy pixel nahore putPixel(x, y+2); // druhy pixel dole } if (pointShape==PointShape.XCross3x3 || pointShape==PointShape.Block3x3 || pointShape==PointShape.XCross5x5 || pointShape==PointShape.Diamond5x5 || pointShape==PointShape.Block5x5) { putPixel(x-1, y-1); // diagonalni pixely putPixel(x-1, y+1); putPixel(x+1, y-1); putPixel(x+1, y+1); } if (pointShape==PointShape.XCross5x5 || pointShape==PointShape.Block5x5) { putPixel(x-2, y-2); putPixel(x-2, y+2); putPixel(x+2, y-2); putPixel(x+2, y+2); } if (pointShape==PointShape.Block5x5) { putPixel(x-1, y-2); putPixel(x-1, y+2); putPixel(x+1, y-2); putPixel(x+1, y+2); putPixel(x-2, y-1); putPixel(x-2, y+1); putPixel(x+2, y-1); putPixel(x+2, y+1); } } // ----------------------------------------------------------------------- // Vlastni aplikace algoritmu IFS // ----------------------------------------------------------------------- private void generateIFS(double data1[][], // predavana data prvniho IFS systemu double data2[][], // predavana data druheho IFS systemu int maxIter, // maximalni pocet iteraci int startIter, // pocet startovnich iteraci int width, // horizontalni rozliseni obrazku int height) { // vertikalni rozliseni obrazku double x1=0, y1=0, x2=0, y2=0; // generovane souradnice double xmin=1e10, xmax=-1e10; // obdelnik opsany IFS fraktalu double ymin=1e10, ymax=-1e10; int x, y, k; double pp, sum; double delitel=1.0; Random r=new Random(0); // generator nahodnych cisel double a[][]=new double [5][7]; // matice s koeficienty IFS systemu for (int j=0; j<5; j++) { // prenos koeficientu IFS systemu for (int i=0; i<7; i++) { // a smichani prvniho a druheho systemu a[j][i]=(1.0-morphRatio)*data1[j+firstIFS*5][i] +(morphRatio)*data2[j+secondIFS*5][i]; } } for (int i=0; i<maxIter; i++) { // pro vsechny iterace int counter=0; pp=r.nextDouble(); sum=0; // na zaklade nahodneho cisla for (k=0; sum<=pp; k++) // najit transformaci sum+=a[k][6]; k--; x2=x1*a[k][0] + y1*a[k][1] + a[k][4]; // aplikovat transformaci y2=x1*a[k][2] + y1*a[k][3] + a[k][5]; x1=x2; y1=y2; if (i>startIter) { // pokud byl prekrocen pocet x2=(x1-xmin)*(double)width/delitel; // startovnich iteraci y2=(y1-ymin)*(double)height/delitel; x=(int)x2; y=(int)y2; // vypocitat a zobrazit pozice pixelu putPoint(x, y); } else { // pokud se jedna o startovni iterace if (x1<xmin) xmin=x1; // provest vypocet opsaneho obdelnika if (y1<ymin) ymin=y1; if (x1>xmax) xmax=x1; if (y1>ymax) ymax=y1; } if (i==startIter) { // zafixovat opsany obdelnik xmin*=1.1; xmax*=1.1; ymin*=1.1; ymax*=1.1; delitel=(xmax-xmin); if (ymax-ymin>xmax-xmin) delitel=ymax-ymin; } counter++; /* if (counter==100) { // prubezne vypisovat prubeh operaci label.setText("Points: "+String.valueOf(i)); // na rychlych pocitacich neni zapotrebi counter=0; } */ } } // ----------------------------------------------------------------------- // Funkce, ktera rozbehne cele vypocetni vlakno. // ----------------------------------------------------------------------- public void run() { prepareGUI(); // vytvoreni vsech GUI prvku label.setText("Initializing"); initPixmap(); // inicializace pixmapy generateIFS(data, data, maxIter, startIter, width, height); // vlastni vygenerovani IFS fraktalu label.setText("Finishing"); finishGUI(); // fitrace a zavreni pomocneho okna } // ----------------------------------------------------------------------- // Vypocet IFS v jednom vypocetnim vlaknu. // ----------------------------------------------------------------------- public void runInSingleThread() { initPixmap(); // inicializace pixmapy generateIFS(data, data, maxIter, startIter, width, height); // vlastni vygenerovani IFS fraktalu } } // ---------------------------------------------------------------------------- // Konec tridy IFS. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // finito // ----------------------------------------------------------------------------