// ----------------------------------------------------------------------------
// application: Diffuse demo
// author: Pavel Tisnovsky
// file name: Diffuse7.java
// directory: java
// date: 25.07.2004
// description: Demonstracni aplikace pro vytvoreni a zobrazeni fraktalniho
// objektu, ktery je zalozeny na simulaci difuze. Pri vytvareni
// difuze se postupne generuji body, jez se spojite pohybuji
// v zadane bitmape a tvori v ni tak cestu. Pocatek generovani
// techto bodu lezi na kruznici, ktera se postupne zvetsuje od
// stredu vznikajiciho obrazce difuze.
// ----------------------------------------------------------------------------
// Nasledujici radky jsou urceny pro spusteni appletu v programu AppletViewer:
//
// <applet code="Diffuse7.class" width="640" height="400">
// </applet>
//
// pro kompatibilitu se starsi JVM firmy Microsofti se musi provest preklad
// pomoci prikazu:
// javac -target 1.1 Diffuse7.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.
// ------------------------------------------------------------------------
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]=0xffffffff; // provest vymazani pixelu
pos++;
}
}
}
// ------------------------------------------------------------------------
// Tato metoda provede filtraci pixmapy s filtrem typu:
// rozmazani v bloku 2x2 pixely s vyberem ve tvaru bloku.
// ------------------------------------------------------------------------
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.
// ------------------------------------------------------------------------
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.
// ------------------------------------------------------------------------
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.
// ------------------------------------------------------------------------
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.
// ------------------------------------------------------------------------
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.
// ------------------------------------------------------------------------
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.
// ------------------------------------------------------------------------
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.
// ------------------------------------------------------------------------
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.
// ------------------------------------------------------------------------
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.
// ------------------------------------------------------------------------
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.
// ------------------------------------------------------------------------
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.
// ------------------------------------------------------------------------
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.
// ------------------------------------------------------------------------
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 point shape\n"+
"2. choose seed shape (set of starting points)\n"+
"3. adjust number of generated points in a box\n"+
"4. set filter type\n"+
"5. set box count\n"+
"6. set radius step\n"+
"7. then press the 'Recalc' button\n"+
"8. 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("Diffuse 7 - 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(
"Diffuse 7 demo\n\n"+
"version 1.0\n"+
"Author: Pavel Tisnovsky\n"+
"Date: 2004-07-25\n"+
"http://www.fit.vutbr.cz/~tisnovpa\n"
);
visible=true;
Button buttonOK=new Button("ok");
Label label=new Label("About Diffuse 7");
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("Diffuse 7 - About"); // 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 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("Diffuse 7 - 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 seminek.
// ----------------------------------------------------------------------------
interface SeedShape {
int OnePoint= 0, // seminko ve tvaru jednoho bodu
TwoPoints= 1, // dva body na usecce
ThreePoints= 2, // tri body ve vrcholech trojuhelnika
FourPoints= 3, // ctyri body ve vrcholech ctverce
ShortCenterLine= 4, // cast usecky
CenterLine= 5, // usecka ve spodni casti obrazce
Square= 6, // ctverec
Border= 7, // ctverec az k okrajum bitmapy
SmallCircle= 8, // mala kruznice
NormalCircle= 9, // normalni kruznice
BigCircle= 10; // vetsi kruznice
}
// ----------------------------------------------------------------------------
// Konec rozhrani SeedShape.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// 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.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// 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 Diffuse7 extends Applet implements
Runnable,
ActionListener,
ItemListener,
AdjustmentListener,
SeedShape,
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
int points=10000; // pocet vsech iteraci
int boxCount=100; // pocet boxu
int radiusStep=1; // zmena radiusu
int pointShape=PointShape.OnePixel;// typ vykreslovanych bodu
int seedShape=SeedShape.OnePoint; // tvar seminka
int filterType=FilterType.Cross3x3;// typ pouziteho filtru
boolean neighboorType=false; // typ okoli pixelu
// vytvoreni vsech panelu pouzitych v appletu
ImagePanel panelLeft= new ImagePanel(ImageWidth, ImageHeight);
ImagePanel panelCenter= new ImagePanel(ImageWidth, ImageHeight);
Panel panelUp= new Panel(new GridLayout(2, 4, 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, panelLeft.pixels, panelCenter.pixels);
// objekt, ve kterem je implementovan algoritmus difuze
Diffuser diffuser=null;
// vytvoreni vsech textovych navesti pouzitych v appletu
Label labelPointShape= new Label("Point shape");
Label labelSeedShape= new Label("Seed shape");
Label labelNeighbourHoodType= new Label("Neighbourhood type");
Label labelFilterType= new Label("Filter");
Label labelPointsInBox= new Label("Max. points: "+String.valueOf(points));
Label labelBoxCount= new Label("Box count: "+String.valueOf(boxCount));
Label labelRadiusStep= new Label("Radius step: "+String.valueOf(radiusStep));
// vytvoreni vsech list-boxu pouzitych v appletu
Choice choicePointShape= new Choice(); // list-box pro vyber tvaru bodu
Choice choiceSeedShape= new Choice(); // list-box pro vyber tvaru seminka
Choice choiceNeigbourhoodType= new Choice(); // list-box pro vyber okoli pixelu
Choice choiceFilter= new Choice(); // list-box pro vyber aktivniho filtru
// 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 scrollBarPoints= new Scrollbar(Scrollbar.HORIZONTAL, points, 1000, 100, 20000+1000);
Scrollbar scrollBarBoxCount= new Scrollbar(Scrollbar.HORIZONTAL, boxCount, 20, 50, 270);
Scrollbar scrollBarRadiusStep= new Scrollbar(Scrollbar.HORIZONTAL, radiusStep, 1, 1, 21);
// ------------------------------------------------------------------------
// 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(labelPointShape); // pridani vsech textovych navesti
panelUp.add(labelSeedShape); // do horniho panelu
panelUp.add(labelNeighbourHoodType);
panelUp.add(labelFilterType);
panelUp.add(choicePointShape); // pridani vsech list-boxu
panelUp.add(choiceSeedShape);
panelUp.add(choiceNeigbourhoodType);
panelUp.add(choiceFilter);
// 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 5x5 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 NeighbourhoodType
choiceNeigbourhoodType.setEnabled(true); // naplneni list-boxu s typem okoli pixelu
choiceNeigbourhoodType.add("4 pixels");
choiceNeigbourhoodType.add("8 pixels");
choiceNeigbourhoodType.select(0); // vyber aktivni polozky z list-boxu
choiceNeigbourhoodType.addItemListener(this);// nastaveni zpracovani udalosti od list-boxu
// prace s list-boxem SeedShape
choiceSeedShape.setEnabled(true); // naplneni list-boxu texty a povoleni list-boxu
choiceSeedShape.add("One point");
choiceSeedShape.add("Two points");
choiceSeedShape.add("Three points");
choiceSeedShape.add("Four points");
choiceSeedShape.add("Short center line");
choiceSeedShape.add("Center line");
choiceSeedShape.add("Square");
choiceSeedShape.add("Border size");
choiceSeedShape.add("Small circle");
choiceSeedShape.add("Normal circle");
choiceSeedShape.add("Big circle");
choiceSeedShape.select(seedShape); // vyber aktivni polozky z list-boxu
choiceSeedShape.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
}
// ------------------------------------------------------------------------
// 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(labelPointsInBox); // pridani vsech textovych navesti
panelDown.add(labelBoxCount);
panelDown.add(labelRadiusStep);
panelDown.add(scrollBarPoints); // pridani vsech slideru
panelDown.add(scrollBarBoxCount);
panelDown.add(scrollBarRadiusStep);
scrollBarPoints.addAdjustmentListener(this);// nastaveni reakci na udalosti slideru
scrollBarBoxCount.addAdjustmentListener(this);
scrollBarRadiusStep.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 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
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("Center", panelCenter); // pridat centralni 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(panelCenter); // zrusit centralni panel
}
// ------------------------------------------------------------------------
// Tato metoda se zavola vzdy pri nastartovani appletu.
// Metoda je volana z virtualniho stroje Javy (JVM).
// ------------------------------------------------------------------------
public void start() {
}
// ------------------------------------------------------------------------
// 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
panelLeft.redraw(false);
applyFilter();
panelCenter.redraw(false);
}
if (o==buttonRecalc) { // prepocitani celeho fraktalu
recalcFractal();
}
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();
}
if (o==choiceSeedShape) {
seedShape=choiceSeedShape.getSelectedIndex();
}
if (o==choiceFilter) { // uzivatel zmenil filtr aplikovany na obrazek
filterType=choiceFilter.getSelectedIndex();// ziskat index vybraneho filtru
applyFilter();
panelCenter.redraw(false);
}
if (o==choiceNeigbourhoodType) { // uzivatel zmenil typ okoli pixelu
neighboorType=(choiceNeigbourhoodType.getSelectedIndex()==1);
}
}
// ------------------------------------------------------------------------
// 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==scrollBarPoints) { // zmena poctu bodu generovanych v boxu
points=scrollBarPoints.getValue(); // ziskat pocet bodu
labelPointsInBox.setText("Max. points: "+String.valueOf(points));
}
if (o==scrollBarBoxCount) { // zmena poctu boxu
boxCount=scrollBarBoxCount.getValue(); // ziskat novou hodnotu
labelBoxCount.setText("Box count: "+String.valueOf(boxCount));
}
if (o==scrollBarRadiusStep) { // zmena radiusu
radiusStep=scrollBarRadiusStep.getValue();// ziskat novou hodnotu
labelRadiusStep.setText("Radius step: "+String.valueOf(radiusStep));
}
}
// ------------------------------------------------------------------------
// 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() {
if (diffuser!=null) {
if (diffuser.isAlive())
return;
}
diffuser=new Diffuser(); // vytvorit diffuser
diffuser.setPixels(panelLeft.pixels); // nastavit jeho parametry
diffuser.setSize(ImageWidth, ImageHeight);
diffuser.setMaxPoints(points);
diffuser.setBoxCount(boxCount);
diffuser.setRadiusStep(radiusStep);
diffuser.setPointShape(pointShape);
diffuser.setSeedShape(seedShape);
diffuser.setNeighbourhoodType(neighboorType);
diffuser.setObject(this);
diffuser.start(); // a spustit ho
}
/*
// -----------------------------------------------------------------------
// 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.
// V tomto pripade se vsak vytvori dalsi soubor .class s anonymni tridou
// se jmenem Listener.
// -----------------------------------------------------------------------
public static void main(String[] args) {
Frame frame=new Frame("Diffuse7");
Applet applet=new Diffuse7();
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 Diffuse7.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Trida, ve krere je implementovan algoritmus simulace difuze.
// ----------------------------------------------------------------------------
class Diffuser 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 boxCount; // pocet boxu
int radiusStep; // zmena radiusu
int maxPoints; // max. pocet bodu
int pointShape; // typ vykreslovych bodu
int seedShape; // tvar seminka
int boxesInRow; // pocet boxu generovanych v jednom radku
boolean neighboorType; // typ okoli pixelu
boolean pixels[][]; // pomocna mrizka, ve ktere se bude generovat
boolean yCoordinateType; // zpusob vypoctu pocatecni y-ove souradnice
Diffuse7 object; // objekt s panely, do kterych se kresli
// -----------------------------------------------------------------------
// Konstruktor, ve kterem se nastavi vhodne implicitni hodnoty.
// -----------------------------------------------------------------------
public Diffuser() {
pixelSrc=null;
width=height=100;
maxPoints=10000;
pointShape=seedShape=0;
boxCount=100;
radiusStep=1;
neighboorType=false;
pixels=null;
yCoordinateType=true;
}
// -----------------------------------------------------------------------
// 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 setMaxPoints(int maxPoints) {
this.maxPoints=maxPoints;
}
// -----------------------------------------------------------------------
// Zmena poctu boxu.
// -----------------------------------------------------------------------
public void setBoxCount(int boxCount) {
this.boxCount=boxCount;
}
// -----------------------------------------------------------------------
// Zmena delty radiusu kruznice.
// -----------------------------------------------------------------------
public void setRadiusStep(int radiusStep) {
this.radiusStep=radiusStep;
}
// -----------------------------------------------------------------------
// Nastaveni typu okoli pixelu, na kterem se provadi testy.
// -----------------------------------------------------------------------
public void setNeighbourhoodType(boolean neighboorType) {
this.neighboorType=neighboorType;
}
// -----------------------------------------------------------------------
// Nastaveni tvaru, ktery se bude ukladat do pracovni bitmapy.
// -----------------------------------------------------------------------
public void setPointShape(int pointShape) {
this.pointShape=pointShape;
}
// -----------------------------------------------------------------------
// Nastaveni seminka - pocatecnich bodu fraktalniho obrazce.
// -----------------------------------------------------------------------
public void setSeedShape(int seedShape) {
this.seedShape=seedShape;
}
// -----------------------------------------------------------------------
// Predani reference hlavniho GUI objektu.
// -----------------------------------------------------------------------
public void setObject(Diffuse7 o) {
object=o;
}
// -----------------------------------------------------------------------
// Nastaveni zpusobu vypoctu y-ove pocatecni souradnice.
// -----------------------------------------------------------------------
public void setYCoordinateType(boolean yCoordinate) {
this.yCoordinateType=yCoordinate;
}
// -----------------------------------------------------------------------
// Vytvoreni a zobrazeni pomocneho okna, ve kterem se zobrazuje prubeh prace.
// -----------------------------------------------------------------------
private void prepareGUI() {
frame=new Frame("Computing diffuse");
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() {
label.setText("Filtering bitmaps");
object.panelLeft.redraw(false);
object.applyFilter(); // aplikace filtru na bitmapu
object.panelCenter.redraw(false);
frame.setVisible(false); // a zruseni pomocneho okna
frame.dispose();
}
// -----------------------------------------------------------------------
// Vytvoreni a inicializace pomocneho pole - plosne rastrove bitove mrizky,
// do ktere se bude obrazec difuze generovat.
// -----------------------------------------------------------------------
private void initBitmap() {
pixels=new boolean[height][width];
for (int j=0; j<height; j++) {
for (int i=0; i<width; i++) {
pixels[j][i]=false; // vsechny pixely nastavit
} // na stejnou hodnotu false
}
}
// -----------------------------------------------------------------------
// Kopie dat z pomocne bitmapy (pomocne rastrove bitove mrizky) do pixmapy,
// ktera se bude zobrazovat v hlavnim okne aplikace ci appletu.
// -----------------------------------------------------------------------
private void copyBitmapToPixmap() {
int pos=0;
for (int j=0; j<height; j++) {
for (int i=0; i<width; i++) { // pixel je bud cerny nebo bily
pixelSrc[pos]=pixels[j][i] ? // podle pravdivostni hodnoty ulozene v poli pixelu
0xff000000: // nastavit cerny pixel nebo
0xffffffff; // nastavit bily pixel
pos++; // index do cilove pixmapy
} // (ktera je typu truecolor)
}
}
// -----------------------------------------------------------------------
// Tato metoda provadi inicializaci seminka - pocatecnich bodu ve vznika-
// jicim fraktalnim objektu, ke kterym se v dalsim prubehu simulace difuze
// pridavaji dalsi body.
// -----------------------------------------------------------------------
private void initSeed() {
int wh=width/2; // horizontalni stred pracovni bitmapy
int hh=height/2; // vertikalni stred pracovni bitmapy
int wh1=1*width/3; // prvni horizontalni tretina pracovni bitmapy
int wh2=2*width/3; // druha horizontalni tretina pracovni bitmapy
int hh1=1*height/3; // prvni vertikalni tretina pracovni bitmapy
int hh2=2*height/3; // druha vertikalni tretina pracovni bitmapy
switch (seedShape) {
case SeedShape.OnePoint: // generuje se pouze jeden bod
pixels[hh][wh]=true; // uprostred pracovni bitmapy
break;
case SeedShape.TwoPoints: // generuji se dva symetricky postavene body
pixels[hh][wh1]=true;
pixels[hh][wh2]=true;
break;
case SeedShape.ThreePoints: // generuji se tri symetricky postavene body
pixels[hh][wh]=true;
pixels[hh][wh1]=true;
pixels[hh][wh2]=true;
break;
case SeedShape.FourPoints: // generuji se ctyri
pixels[hh][width/5]=true; // symetricky postavene body
pixels[hh][2*width/5]=true;
pixels[hh][3*width/5]=true;
pixels[hh][4*width/5]=true;
break;
case SeedShape.ShortCenterLine: // generuje se kontinualni
for (int i=wh1; i<=wh2; i++) // usecka uprostred bitmapy
pixels[hh][i]=true;
break;
case SeedShape.CenterLine: // generuje se usecka ve stredu bitmapy
for (int i=0; i<width; i++)
pixels[hh][i]=true;
break;
case SeedShape.Square: // generuje se ctverec ve stredu bitmapy
for (int i=wh1; i<=wh2; i++) {
pixels[hh1][i]=true;
pixels[hh2][i]=true;
}
for (int i=hh1; i<=hh2; i++) {
pixels[i][wh1]=true;
pixels[i][wh2]=true;
}
break;
case SeedShape.Border: // generuje se okraj z radky pixelu
for (int i=0; i<width; i++) { // usporadanych okolo cele bitmapy
pixels[0][i]=true;
pixels[height-1][i]=true;
}
for (int i=0; i<height; i++) {
pixels[i][0]=true;
pixels[i][width-1]=true;
}
break;
case SeedShape.SmallCircle: // generuje se mala kruznice uprostred bitmapy
{
double r=wh/4.0;
for (int i=0; i<1000; i++) {
double x=wh+r*Math.cos((double)i);
double y=hh+r*Math.sin((double)i);
pixels[(int)y][(int)x]=true;
}
}
break;
case SeedShape.NormalCircle: // generuje se kruznice uprostred bitmapy
{
double r=wh/2.0;
for (int i=0; i<1000; i++) {
double x=wh+r*Math.cos((double)i);
double y=hh+r*Math.sin((double)i);
pixels[(int)y][(int)x]=true;
}
}
break;
case SeedShape.BigCircle: // generuje se velka kruznice uprostred bitmapy
{
double r=wh-9.0;
for (int i=0; i<1000; i++) {
double x=wh+r*Math.cos((double)i);
double y=hh+r*Math.sin((double)i);
pixels[(int)y][(int)x]=true;
}
}
break;
default:
pixels[hh][wh]=true;
break;
}
}
// -----------------------------------------------------------------------
// Tato metoda vrati pravdivostni hodnotu true v pripade, ze se v okoli
// zadaneho pixelu vyskytuje jiny pixel, jez nalezi do vytvareneho
// fraktalniho (difuzniho) objektu. V opacnem pripade se z funkce vrati
// pravdivostni hodnota false. Typ okoli je predan v parametru type.
// -----------------------------------------------------------------------
private boolean neighboor(boolean type, int i, int j) {
// kontrola mezi pro pristup do pole
if (i<2 || j<2 || i>width-2 || j>height-2) return false;
return type ?
pixels[j-1][i-1] | // osmiokoli pixelu
pixels[j-1][i] |
pixels[j-1][i+1] |
pixels[j][i-1] |
pixels[j][i+1] |
pixels[j+1][i-1] |
pixels[j+1][i] |
pixels[j+1][i+1]
:
pixels[j-1][i] | // ctyrokoli pixelu
pixels[j][i-1] |
pixels[j][i+1] |
pixels[j+1][i]
;
}
// -----------------------------------------------------------------------
// Vykresleni bodu, tj. jednoho pixelu ci nekolika pixelu, do temporalni
// bitmapy (plosne rastrove bitove mrizky) podle uzivatelem predem
// zvoleneho tvaru bodu. Tvar bodu je specifikovan v promenne pointShape.
// -----------------------------------------------------------------------
private void putPoint(int x, int y) {
if (x<3) x=3; // zabranit zapisum
if (x>=width-3) x=width-4; // mimo pole (bitmapu)
if (y<3) y=3;
if (y>=height-3) y=height-3;
if (pointShape!=PointShape.Diamond3x3 && // krome dvou specialnich tvaru
pointShape!=PointShape.Diamond5x5) {
pixels[y][x]=true; // vykreslit prostredni pixel
}
if (pointShape==PointShape.Cross3x3 ||
pointShape==PointShape.Diamond3x3 ||
pointShape==PointShape.Block3x3 ||
pointShape==PointShape.Cross5x5 ||
pointShape==PointShape.Block5x5 ||
pointShape==PointShape.Horizontal3 ||
pointShape==PointShape.Horizontal5) {
pixels[y][x-1]=true; // nastavit pixel nalevo
pixels[y][x+1]=true; // a pixel napravo
} // od prostredniho pixelu
if (pointShape==PointShape.Horizontal5 ||
pointShape==PointShape.Cross5x5 ||
pointShape==PointShape.Diamond5x5 ||
pointShape==PointShape.Block5x5) {
pixels[y][x-2]=true; // nastavit druhy pixel nalevo
pixels[y][x+2]=true; // a druhy pixel napravo
} // od prostredniho pixelu
if (pointShape==PointShape.Cross3x3 ||
pointShape==PointShape.Diamond3x3 ||
pointShape==PointShape.Block3x3 ||
pointShape==PointShape.Cross5x5 ||
pointShape==PointShape.Block5x5 ||
pointShape==PointShape.Vertical3 ||
pointShape==PointShape.Vertical5) {
pixels[y-1][x]=true; // nastavit pixel nahore
pixels[y+1][x]=true; // a pixel dole
} // od prostredniho pixelu
if (pointShape==PointShape.Vertical5 ||
pointShape==PointShape.Cross5x5 ||
pointShape==PointShape.Diamond5x5 ||
pointShape==PointShape.Block5x5) {
pixels[y-1][x]=true; // nastavit druhy pixel nahore
pixels[y+1][x]=true; // a druhy pixel dole
} // od prostredniho pixelu
if (pointShape==PointShape.XCross3x3 ||
pointShape==PointShape.Block3x3 ||
pointShape==PointShape.XCross5x5 ||
pointShape==PointShape.Diamond5x5 ||
pointShape==PointShape.Block5x5) {
pixels[y-1][x-1]=true; // nastavit ctyri diagonalni pixely
pixels[y+1][x-1]=true;
pixels[y-1][x+1]=true;
pixels[y+1][x+1]=true;
}
if (pointShape==PointShape.XCross5x5 ||
pointShape==PointShape.Block5x5) {
pixels[y-2][x-2]=true; // nastavit ctyri diagonalni pixely
pixels[y+2][x-2]=true; // ve vzdalenosti 2
pixels[y-2][x+2]=true; // od prostredniho pixelu
pixels[y+2][x+2]=true;
}
if (pointShape==PointShape.Block5x5) {
pixels[y-2][x-1]=true; // nastavit zbyvajicich osm pixelu
pixels[y+2][x-1]=true; // v bloku 5x5 pixelu
pixels[y-2][x+1]=true;
pixels[y+2][x+1]=true;
pixels[y-1][x-2]=true;
pixels[y+1][x-2]=true;
pixels[y-1][x+2]=true;
pixels[y+1][x+2]=true;
}
}
// -----------------------------------------------------------------------
// Aplikace algoritmu difuze, jez je zalozen na postupnem pohybu bodu
// v pracovni bitmape (binarni rastrove mrizce). Pocatecni pozice bodu
// lezi na kruznici, ktera se pri behu algoritmu plynule zvetsuje od
// stredu vznikajiciho obrazce difuze az do okraju vytvarene bitmapy.
// -----------------------------------------------------------------------
private void applyDiffuse() {
final int CounterThreshold=200; // pocet bodu pro provedeni vypisu
// do GUI okna appletu ci aplikace
int counter=0; // pocitadlo vytvorenych bodu
int points=0; // pocitadlo vsech bodu
int dist; // vzdalenost od stredu obrazce
float alpha; // uhel vytvoreneho bodu od x-ove osy
int x, y; // souradnice generovanych bodu
int box; // pocitadla smycek
int originX=width>>1; // souradnice stredu pracovni bitmapy
int originY=height>>1;
int radius; // maximalni povoleny polomer kruznice
boolean looking;
if (originX<originY) // vypocet maximalniho povoleneho
radius=originX; // polomeru kruznice z rozmeru
else // pracovni bitmapy
radius=originY;
putPoint(originX, originY); // vytvorit bod ve stredu obrazce
// (tento bod je vzdy soucasti seminka)
// hlavni programova smycka, jez obstarava zmenu velikosti kruznice, na ktere se
for (dist=0; dist<radius-1; dist+=radiusStep) { // vytvari pocatecni pozice bodu
box=0;
// vnitrni smycka pro vygenerovani zadaneho poctu oblasti
while (box<boxCount) {
// uhel odchylky mereny od horizontalni osy
alpha=(float)(Math.random()*2.0*Math.PI);
// souradnice leveho horniho rohu oblasti
// prevedeneho na pixely
x=(int)(originX+dist*Math.cos(alpha));
y=(int)(originY+dist*Math.sin(alpha));
looking=true; // nastavit priznak hledani bodu
// vnitrni smycka pro nalezeni mista pripojeni pixelu k obrazci difuze
do {
x+=Math.random()*3.0-1; // posun pixelu v plose
y+=Math.random()*3.0-1; // na jeho osmiokoli
if (x<1) x++; // kontrola, zda pixel
if (x>width-2) x--; // lezi uvnitr povolene
if (y<1) y++; // oblasti v bitmape
if (y>height-2) y--;
// pokud se pixel dotkl stavajiciho objektu
if (neighboor(neighboorType, x, y)){
putPoint(x, y); // je k nemu pripojen
looking=false; // hledani lze ukoncit
points++; // zvysit pocitadlo vsech pripojenych bodu
box++;
}
// po dosazeni dostatecneho poctu pripojenych pixelu
counter++; // prubezny vypis prace programu
if (counter==CounterThreshold) {
label.setText("Points: " // do GUI okna appletu ci aplikace
+String.valueOf(points)
+" dist: "
+String.valueOf(dist));
counter=0;
}
} while (looking); // interni smycku ukoncit az po pripojeni
} // pixelu k obrazci difuze
} // konec hlavni programove smycky
}
// -----------------------------------------------------------------------
// Funkce, ktera rozbehne cele vypocetni vlakno.
// -----------------------------------------------------------------------
public void run() {
prepareGUI(); // vytvoreni vsech GUI prvku
label.setText("Initializing");
initBitmap(); // inicializace bitmapy
initSeed(); // inicializace seminka
applyDiffuse(); // aplikace algoritmu difuze
label.setText("Finishing");
copyBitmapToPixmap(); // kopie pracovni bitmapy do vysledne pixmapy
finishGUI(); // fitrace a zavreni pomocneho okna
}
}
// ----------------------------------------------------------------------------
// Konec tridy Diffuser.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// finito
// ----------------------------------------------------------------------------