// ----------------------------------------------------------------------------
// 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
// ----------------------------------------------------------------------------