// ----------------------------------------------------------------------------
// Demonstracni priklad k serialu "Fraktaly v pocitacove grafice"
// ----------------------------------------------------------------------------
// application: Linear IFS (L-IFS) demo
// author: Pavel Tisnovsky
// file name: LinearIFS.java
// directory: java
// date: 28.06.2006
// description: Demonstracni aplikace pro vytvoreni, editaci a zobrazeni
// fraktalu zalozenych na linearizovanych systemech IFS (L-IFS).
// Podrobnejsi popis teto demonstracni aplikace je popsan primo
// v clanku.
// ----------------------------------------------------------------------------
// Nasledujici radky jsou urceny pro spusteni appletu v programu AppletViewer:
//
// <applet code="LinearIFS.class" width="896" height="628">
// </applet>
//
// pro kompatibilitu se starsi JVM firmy Microsoft se musi provest preklad
// pomoci prikazu:
// javac -target 1.1 LinearIFS.java
// ----------------------------------------------------------------------------
// seznam importovanych balicku
// ----------------------------------------------------------------------------
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.applet.Applet;
// ----------------------------------------------------------------------------
// Vsechny metody tohoto appletu jsou napsany pouze v jedine tride tak, aby se
// vygeneroval pouze jeden soubor .class, coz ulehci a zrychli praci interneto-
// veho prohlizece, protoze se nebude zbytecne otevirat vice sitovych spojeni.
// 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 LinearIFS extends Applet implements Runnable, ActionListener, ItemListener, AdjustmentListener {
static final int ImageWidth=384; // sirka bitmapy s fraktalem
static final int ImageHeight=384; // vyska bitmapy s fraktalem
static final int DrawingWidth=ImageWidth; // sirka kresby pouzivane pro konstrukci fraktalu
static final int DrawingHeight=ImageHeight+150; // vyska kresby pouzivane pro konstrukci fraktalu
static final int TextBegin=ImageWidth+10; // horizontalni zacatek informacniho textu
static final int TextHeight=120; // vyska informacniho textu
static final int ShowHelp=1; // priznak, ze se ma na plochu appletu vypisovat napoveda
static final int ShowInfo=2; // priznak, ze se maji na plochu appletu vypisovat informace o pameti
static final int ShowAbout=3; // priznak, ze se maji na plochu appletu vypisovat informace o aplikaci
static final int QuickFractalIterations=1000; // pocet iteraci pri rychlem prekreslovani fraktalu
static final int QuickFractalStartIterations=10;// pocet startovnich iteraci pri rychlem prekreslovani fraktalu
// pole specifikujici maximalni pocet iteraci pro vsechny zabudovane modely
static final int MaxIterations[]= { 50000, 50000, 50000, 50000, 50000, 50000, 50000, 50000,
50000, 50000, 50000, 50000, 50000, 50000, 50000, 50000};
// pole specifikujici pocet startovnich iteraci pro vsechny zabudovane modely
static final int StartIterations[]={ 100, 203, 100, 100, 94, 100, 100, 100,
100, 100, 100, 100, 76, 94, 100, 1};
// pole specifikujici pocet pouzitych vertexu pro vsechny zabudovane modely
static final int MaxVertexes[]= { 3, 4, 5, 6, 7, 8, 5, 6,
7, 7, 8, 8, 8, 7, 8, 6};
// pole specifikujici index filtru pro vsechny zabudovane modely
static final int Filters[]= { 5, 5, 5, 5, 1, 5, 5, 5,
5, 5, 5, 5, 1, 1, 0, 0};
// pole specifikujici rozdeleni usecky ve smeru x-ove osy pro vsechny zabudovane modely
static final double XFractions[]= { 0.500, 0.594, 0.600, 0.650, 0.629, 0.662, 0.600, 0.600,
0.630, 0.630, 0.667, 0.587, 0.587, 0.626, 0.500, 0.015};
// pole specifikujici rozdeleni usecky ve smeru y-ove osy pro vsechny zabudovane modely
static final double YFractions[]= { 0.500, 0.583, 0.600, 0.650, 0.640, 0.666, 0.600, 0.600,
0.640, 0.640, 0.669, 0.583, 0.583, 0.623, 0.500, 0.019};
// pole pozice vertexu pro vsechny zabudovane modely
static final int Vertexes[][]= {
{194, 107, 74, 314, 314, 314, 314, 314, 127, 127, 255, 127, 127, 255, 255, 255},// sierpinsky triangle
{194, 107, 74, 314, 314, 314, 194, 238, 127, 127, 255, 127, 127, 255, 255, 255},// snowflake 4 vertices
{192, 312, 306, 229, 262, 95, 122, 95, 78, 229, 255, 127, 127, 255, 255, 255},// snowflake 5 vertices
{132, 295, 252, 295, 312, 192, 252, 88, 132, 88, 72, 192, 127, 255, 255, 255},// snowflake 6 vertices
{132, 295, 252, 295, 312, 192, 252, 88, 132, 88, 72, 192, 191, 191, 255, 255},// snowflake 7 vertices
{311, 191, 275, 275, 191, 311, 107, 275, 71, 191, 107, 107, 191, 71, 275, 107},// snowflake 8 vertices
{192, 312, 306, 229, 262, 95, 122, 95, 78, 229, 255, 127, 127, 255, 255, 255},// star 5 vertices
{132, 295, 252, 295, 312, 192, 252, 88, 132, 88, 72, 192, 127, 255, 255, 255},// star 6 vertices
{132, 295, 252, 295, 312, 192, 252, 88, 132, 88, 72, 192, 191, 191, 255, 255},// star 7 vertices version A
{132, 295, 252, 295, 312, 192, 252, 88, 132, 88, 72, 192, 191, 191, 255, 255},// star 7 vertices version B
{311, 191, 275, 275, 191, 311, 107, 275, 71, 191, 107, 107, 191, 71, 275, 107},// star 8 vertices
{ 69, 69, 314, 69, 69, 314, 314, 314, 129, 123, 257, 123, 129, 251, 257, 251},// rectangle version 1
{ 69, 69, 314, 69, 69, 314, 314, 314, 104, 105, 163, 106, 103, 164, 171, 163},// rectangle version 2
{ 75, 305, 185, 283, 303, 193, 303, 79, 190, 79, 96, 194, 100, 282, 255, 255},// rocket
{ 69, 69, 314, 69, 69, 314, 314, 314, 127, 127, 255, 127, 127, 255, 255, 255},// base
{132, 295, 252, 295, 312, 192, 252, 88, 132, 88, 72, 192, 127, 255, 255, 255},// bomb
};
// pole matice posloupnosti transformaci pro vsechny zabudovane modely
static final int Restrictions[][]={
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0},
{1,1,1,0,1,1,1,0,1,1,0,1,1,1,0,1,1,0,1,1,1,0,1,1,0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,1,0,1,1,1,0,1,1,0,1,1,1,0,1,1,0,1,1,1,0,1,1,1},
{1,1,1,0,1,1,1,0,1,1,0,1,1,1,0,1,1,0,1,1,1,0,1,1,0,1,1,1,0,1,1,1,1,1,1,0,0,0,0,0,1,1,0,1,0,0,0,0,1,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0},
{1,1,0,0,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
};
int iterations=5000; // pocet vsech iteraci
int startIterations=500; // pocet startovnich iteraci
int filterType=3; // typ pouziteho filtru
double xFraction=0.5; // deleni usecky ve smeru x-ove osy
double yFraction=0.5; // deleni usecky ve smeru y-ove osy
int activeVertexes=3; // pocet aktivnich vrcholu
int selectedVertex=8; // cislo vybraneho vrcholu
int[] vertexX=new int[8]; // pole x-ovych souradnic vrcholu
int[] vertexY=new int[8]; // pole y-ovych souradnic vrcholu
boolean[][] restrictions=new boolean[8][8];// pole s prvky matice posloupnosti transformaci
int drawingMode=ShowAbout; // druh vykreslovanych informaci
boolean fractalNeedsRedraw=true; // priznak, zda se ma prekreslit cely fraktal
static int putpixelMode=0; // vykreslovaci rezim
// vytvoreni vsech panelu pouzitych v appletu
Panel panelUp= new Panel(new GridLayout(2, 4, 5, 5));// horni panel s list-boxy
Panel panelDown= new Panel(new GridLayout(2, 4, 5, 5));// dolni panel se slidery
Panel panelRight= new Panel(new GridLayout(8, 1));// pravy panel s tlacitky
Panel panelCenter= new Panel(); // centralni panel s vykreslovanym fraktalem
Canvas drawing= new Canvas(); // vykreslovaci platno pro konstrukci fraktalu
// vytvoreni vsech textovych navesti pouzitych v appletu
Label labelModel= new Label("Model");
Label labelVertexes= new Label("Vertex count");
Label labelFilter= new Label("Filter");
Label labelPutpixelMode= new Label("Putpixel mode");
Label labelIterations= new Label("Iterations: "+String.valueOf(iterations));
Label labelStartIterations=new Label("Start iterations: "+String.valueOf(startIterations));
Label labelXFraction= new Label("X-fraction: "+String.valueOf(xFraction));
Label labelYFraction= new Label("Y-fraction: "+String.valueOf(yFraction));
// vytvoreni vsech list-boxu pouzitych v appletu
Choice choiceModel= new Choice(); // list-box pro vyber modelu
Choice choiceVertexes= new Choice(); // list-box pro vyber poctu aktivnich vertexu
Choice choiceFilter= new Choice(); // list-box pro vyber aktivniho filtru
Choice choicePutpixelMode= new Choice(); // list-box pro vyber vykreslovaciho rezimu
// vytvoreni vsech tlacitek pouzitych v appletu
Button buttonRedraw= new Button("Redraw");
Button buttonAbout= new Button("About");
Button buttonInfo= new Button("Info");
Button buttonHelp= new Button("Help");
// vytvoreni vsech slideru pouzitych v appletu
Scrollbar scrollBarIterations= new Scrollbar(Scrollbar.HORIZONTAL, iterations, 1000, 100, 100000+1000);
Scrollbar scrollBarStartIterations=new Scrollbar(Scrollbar.HORIZONTAL, startIterations, 500, 100, 5000+500);
Scrollbar scrollBarXFraction= new Scrollbar(Scrollbar.HORIZONTAL, (int)(1000.0*xFraction), 100, 0, 1000+100);
Scrollbar scrollBarYFraction= new Scrollbar(Scrollbar.HORIZONTAL, (int)(1000.0*yFraction), 100, 0, 1000+100);
MemoryImageSource imageSource; // zdroj pixelu pro bitmapu
Image image; // vlastni vykreslovana bitmapa
int[] pixelSrc= new int[ImageWidth*ImageHeight]; // vytvoreni bitmap pro praci
int[] pixelDest= new int[ImageWidth*ImageHeight]; // s fraktalem a filtraci
// ------------------------------------------------------------------------
// 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(labelModel); // pridani vsech textovych navesti
panelUp.add(labelVertexes); // do horniho panelu
panelUp.add(labelFilter);
panelUp.add(labelPutpixelMode);
panelUp.add(choiceModel); // pridani vsech list-boxu
panelUp.add(choiceVertexes);
panelUp.add(choiceFilter);
panelUp.add(choicePutpixelMode);
// prace s list-boxem Model
choiceModel.setEnabled(true); // povoleni list-boxu
choiceModel.add("Sierpinsky triangle"); // a naplneni list-boxu textem
choiceModel.add("Snowflake 3 vertexes");
choiceModel.add("Snowflake 5 vertexes");
choiceModel.add("Snowflake 6 vertexes");
choiceModel.add("Snowflake 7 vertexes");
choiceModel.add("Snowflake 8 vertexes");
choiceModel.add("Star 5 vertexes");
choiceModel.add("Star 6 vertexes");
choiceModel.add("Star 7 vertexes A");
choiceModel.add("Star 7 vertexes B");
choiceModel.add("Star 8 vertexes");
choiceModel.add("Rectangle A");
choiceModel.add("Rectangle B");
choiceModel.add("Rocket");
choiceModel.add("Base");
choiceModel.add("Bomb");
choiceModel.select(1); // vyber aktivni polozky z list-boxu
choiceModel.addItemListener(this); // nastaveni zpracovani udalosti od list-boxu
// prace s list-boxem Vertexes
choiceVertexes.setEnabled(true); // naplneni list-boxu texty a povoleni list-boxu
choiceVertexes.add("three");
choiceVertexes.add("four");
choiceVertexes.add("five");
choiceVertexes.add("six");
choiceVertexes.add("seven");
choiceVertexes.add("eight");
choiceVertexes.select(3); // vyber aktivni polozky z list-boxu
choiceVertexes.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 putpixel mode
choicePutpixelMode.setEnabled(true);
choicePutpixelMode.add("draw white 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(labelIterations); // pridani vsech textovych navesti
panelDown.add(labelStartIterations);
panelDown.add(labelXFraction);
panelDown.add(labelYFraction);
panelDown.add(scrollBarIterations); // pridani vsech slideru
panelDown.add(scrollBarStartIterations);
panelDown.add(scrollBarXFraction);
panelDown.add(scrollBarYFraction);
scrollBarIterations.addAdjustmentListener(this);// nastaveni reakci na udalosti slideru
scrollBarStartIterations.addAdjustmentListener(this);
scrollBarXFraction.addAdjustmentListener(this);
scrollBarYFraction.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(buttonRedraw); // pridani vsech textovych tlacitek
panelRight.add(buttonAbout);
panelRight.add(buttonInfo);
panelRight.add(buttonHelp);
buttonRedraw.addActionListener(this); // nastaveni reakce na udalosti od tlacitek
buttonAbout.addActionListener(this);
buttonInfo.addActionListener(this);
buttonHelp.addActionListener(this);
}
// ------------------------------------------------------------------------
// Tato metoda provede nastaveni centralniho panelu s vyslednym fraktalem.
// Metoda je zavolana behem inicializace aplikace ci appletu.
// ------------------------------------------------------------------------
private void initPanelCenter() {
panelCenter.setBackground(Color.white); // nastaveni barvy pozadi
for (int j=0; j<ImageHeight; j++) // pro vsechny radky bitmapy
for (int i=0; i<ImageWidth; i++) // pro vsechny sloupce bitmapy
pixelDest[i+(j<<8)]=i+(j<<8)+((i-j)<<16)+(255<<24);// vyplnit bitmapu i s alfa kanalem
imageSource=new MemoryImageSource(ImageWidth, ImageHeight, pixelDest, 0, ImageHeight);
image=createImage(imageSource); // vytvoreni bitmapy
}
// ------------------------------------------------------------------------
// Tato metoda provede inicializaci leveho pole pro zobrazeni konstrukce
// L-IFS systemu.
// ------------------------------------------------------------------------
private void initDrawing() {
drawing.setSize(DrawingWidth+10, DrawingHeight+10);// nastveni velikosti pole
drawing.setBackground(Color.white); // nastaveni barvy pozadi
}
// ------------------------------------------------------------------------
// 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
initPanelCenter(); // nastavit centralni panel
initDrawing(); // nastavit levou kreslici plochu
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", drawing); // pridat levou kreslici plochu do plochy aplikace
initModel(1); // inicializace prvniho modelu
}
// ------------------------------------------------------------------------
// Tato metoda se zavola pri destrukci appletu.
// Metoda je volana z virtualniho stroje Javy (JVM)
// ------------------------------------------------------------------------
public void destroy() {
remove(panelRight); // zrusit pravy panel
remove(panelUp); // zrusit horni panel
remove(panelDown); // zrusit dolni panel
remove(panelCenter); // zrusit centralni panel
remove(drawing); // zrusit levou kreslici plochu
}
// ------------------------------------------------------------------------
// 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) {
redrawFractal(); // prekreslit fraktal
redrawDrawing(); // prekreslit kresbu (navrh L-IFS systemu)
switch (drawingMode) { // vyber informace, ktera se ma vypsat
case ShowHelp:
redrawHelp();
break; // zobrazeni napovedy
case ShowInfo:
redrawInfo();
break; // zobrazeni stavovych informaci
case ShowAbout:
redrawAbout();
break; // zobrazeni informaci o aplikaci
default:
break;
}
}
// ------------------------------------------------------------------------
// 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
repaint(); // prekreslit cely applet
}
if (o==buttonAbout) { // text s informacemi o autorech
drawingMode=ShowAbout; // nastavit rezim prekreslovani textu
repaint(); // prekreslit cely applet
}
if (o==buttonHelp) { // text s napovedou
drawingMode=ShowHelp; // nastavit rezim prekreslovani textu
repaint(); // prekreslit cely applet
}
if (o==buttonInfo) { // text s informacemi o aplikaci
drawingMode=ShowInfo; // nastavit rezim prekreslovani textu
repaint(); // prekreslit cely applet
}
}
// ------------------------------------------------------------------------
// 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==choiceModel) { // uzivatel zmenil aktivni model
initModel(choiceModel.getSelectedIndex());// inicializace modelu
repaint(); // prekresleni celeho appletu
}
if (o==choiceFilter) { // uzivatel zmenil filtr aplikovany na obrazek
filterType=choiceFilter.getSelectedIndex();// ziskat index vybraneho filtru
recalcFractal(); // prepocet fraktalu
repaint(); // prekresleni celeho appletu
}
if (o==choiceVertexes) { // uzivatel zmenil pocet aktivnich vertexu
int i=choiceVertexes.getSelectedIndex();// ziskat pocet vertexu
activeVertexes=i+3;
recalcFractal(); // prepocet fraktalu
repaint(); // prekresleni celeho appletu
}
if (o==choicePutpixelMode) {
putpixelMode=choicePutpixelMode.getSelectedIndex();
recalcFractal();
repaint();
}
}
// ------------------------------------------------------------------------
// 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==scrollBarIterations) { // zmena poctu iteraci
iterations=scrollBarIterations.getValue();// ziskat pocet iteraci
labelIterations.setText("Iterations: "+String.valueOf(iterations));
}
if (o==scrollBarStartIterations) { // zmena poctu startovnich iteraci
startIterations=scrollBarStartIterations.getValue();// ziskat pocet startovnich iteraci
labelStartIterations.setText("Start iterations: "+String.valueOf(startIterations));
}
if (o==scrollBarXFraction) { // zmena deleni usecky ve smeru x-ove osy
int i=scrollBarXFraction.getValue(); // ziskat hodnotu deleni
xFraction=(double)i/1000.0;
labelXFraction.setText("X-fraction "+String.valueOf(xFraction));
}
if (o==scrollBarYFraction) { // zmena deleni usecky ve smeru y-ove osy
int i=scrollBarYFraction.getValue(); // ziskat hodnotu deleni
yFraction=(double)i/1000.0;
labelYFraction.setText("Y-fraction "+String.valueOf(yFraction));
}
recalcFractal(); // prepocet celeho fraktalu
repaint(); // a prekresleni appletu
}
// ------------------------------------------------------------------------
// Metoda pro zpracovani udalosti generovanych praci uzivatele.
// Tato metoda je volana z virtualniho stroje jazyka Java (JVM).
// ------------------------------------------------------------------------
public boolean handleEvent(Event e) {
boolean result;
switch (e.id) { // zjistit identifikator udalosti
case Event.MOUSE_DOWN: // udalost vznikla stlacenim tlacitka mysi
if (e.metaDown()) // jedna se o prave tlacitko mysi
onMouseRightButtonDown(e.x, e.y);// zavolat prislusnou callback metodu
else // jedna se o leve tlacitko mysi
onMouseLeftButtonDown(e.x, e.y);// zavolat prislusnou callback metodu
result=true;
break;
case Event.MOUSE_UP: // udalost vznikla pustenim tlacitka mysi
if (e.metaDown()) // jedna se o prave tlacitko mysi
onMouseRightButtonUp(e.x, e.y); // zavolat prislusnou callback metodu
else // jedna se o leve tlacitko mysi
onMouseLeftButtonUp(e.x, e.y); // zavolat prislusnou callback metodu
result=true;
break;
case Event.MOUSE_MOVE: // udalost vznikla pohybem mysi bez stlaceneho tlacitka
onMouseMove(e.x, e.y); // zavolat prislusnou callback metodu
result=true;
break;
case Event.MOUSE_DRAG: // udalost vznikla pohybem mysi se stlacenym tlacitkem
if (e.metaDown()) // jedna se o prave tlacitko mysi
onMouseRightDrag(e.x, e.y); // zavolat prislusnou callback metodu
else // jedna se o leve tlacitko mysi
onMouseLeftDrag(e.x, e.y); // zavolat prislusnou callback metodu
result=true;
break;
default: // dalsi udalosti, ktere se neosetruji
result=false; // se mohou poslat dale do systemu
break;
}
return result;
}
// ------------------------------------------------------------------------
// Tato callback metoda se zavola v pripade, ze uzivatel pustil leve
// tlacitko mysi.
// Metoda je volana po zpracovani udalosti v metode handleEvent().
// ------------------------------------------------------------------------
private void onMouseLeftButtonUp(int x, int y) {
if (fractalNeedsRedraw) { // pokud je zapotrebi prekreslit fraktal
fractalNeedsRedraw=false;
recalcFractal(); // prepocet fraktalu
repaint(); // a prekresleni celeho appletu
}
}
// ------------------------------------------------------------------------
// Tato callback metoda se zavola v pripade, ze uzivatel stlacil leve
// tlacitko mysi.
// Metoda je volana po zpracovani udalosti v metode handleEvent().
// ------------------------------------------------------------------------
private void onMouseLeftButtonDown(int x, int y) {
Point p=new Point(drawing.getLocation()); // ziskat souradnice kresby
x-=p.x; // posun souradnic kurzoru mysi do souradnic
y-=p.y; // kresby
if (x>=150 && x<=150+8*12 && y>=265+ImageHeight-256 && y<=265+8*12+ImageHeight-256) {
x=x-150; x/=12; if (x>7) x=7; // kurzor je v tabulce posloupnosti transformaci
y=y-265-ImageHeight+256; y/=12; if (y>7) y=7;
restrictions[x][y]=!restrictions[x][y]; // zmena tabulky transformaci
recalcFractal(); // prepocet fraktalu
repaint(); // a prekresleni celeho appletu
}
int min=100000; // minimalni vzdalenost kurzoru
int minVertex=0; // mysi od vertexu a cislo vertexu
int i;
if (x>=0 && x<=ImageWidth-1 && y>=0 && y<=ImageHeight-1) { // kurzor je v kresbe
for (i=0; i<activeVertexes; i++) { // projit vsechny vertexy
int xv=vertexX[i]; // souradnice vertexu
int yv=vertexY[i];
int length=Math.abs(x-xv)+Math.abs(y-yv);// vzdalenost kurzoru mysi od vertexu
if (length<min) { // jsme bliz nez pri predchozich vertexech
min=length;
minVertex=i;
}
}
if (min>40) selectedVertex=-1; // pokud je kurzor prilis daleko od vsech vertexu
else selectedVertex=minVertex;
recalcFractal(); // prepocet fraktalu
repaint(); // a prekresleni celeho appletu
}
}
// ------------------------------------------------------------------------
// Tato callback metoda se zavola v pripade, ze uzivatel pustil prave
// tlacitko mysi.
// Metoda je volana po zpracovani udalosti v metode handleEvent().
// ------------------------------------------------------------------------
private void onMouseRightButtonUp(int x, int y) {
return; // v soucasnosti neprovadime zadnou cinnost
}
// ------------------------------------------------------------------------
// Tato callback metoda se zavola v pripade, ze uzivatel stlacil prave
// tlacitko mysi.
// Metoda je volana po zpracovani udalosti v metode handleEvent().
// ------------------------------------------------------------------------
private void onMouseRightButtonDown(int x, int y) {
return; // v soucasnosti neprovadime zadnou cinnost
}
// ------------------------------------------------------------------------
// Tato callback metoda se zavola v pripade, ze uzivatel pohnul s kurzorem
// mysi.
// Metoda je volana po zpracovani udalosti v metode handleEvent().
// ------------------------------------------------------------------------
private void onMouseMove(int x, int y) {
return; // v soucasnosti neprovadime zadnou cinnost
}
// ------------------------------------------------------------------------
// Tato callback metoda se zavola v pripade, ze uzivatel pohnul kurzorem
// mysi se stlacenym levym tlacitkem.
// Metoda je volana po zpracovani udalosti v metode handleEvent().
// ------------------------------------------------------------------------
private void onMouseLeftDrag(int x, int y) {
if (selectedVertex==-1) return; // pokud neni vybrany zadny vertex
if (selectedVertex>activeVertexes) return; // pokud je vybrany vertex mimo aktivni vertexy
Point p=new Point(drawing.getLocation());
x-=p.x; // posun souradnic kurzoru mysi do souradnic
y-=p.y; // obrazku
if (x>=0 && x<=ImageWidth-1 && y>=0 && y<=ImageHeight-1) { // kurzor je v kresbe
vertexX[selectedVertex]=x; // posun vybraneho bodu
vertexY[selectedVertex]=y;
fractalNeedsRedraw=true; // nastaveni priznaku, ze je potreba vykreslit cely fraktal
recalcFractalQuick(); // rychly prepocet fraktalu
repaint(); // a prekresleni celeho appletu
}
}
// ------------------------------------------------------------------------
// Tato callback metoda se zavola v pripade, ze uzivatel pohnul kurzorem
// mysi se stlacenym pravym tlacitkem.
// Metoda je volana po zpracovani udalosti v metode handleEvent().
// ------------------------------------------------------------------------
private void onMouseRightDrag(int x, int y) {
return; // v soucasnosti neprovadime zadnou cinnost
}
// ------------------------------------------------------------------------
// Tato metoda provadi inicializaci nastaveneho modelu fraktalu.
// ------------------------------------------------------------------------
private void initModel(int model) {
xFraction=XFractions[model]; // ziskat pomer deleni usecek ve
yFraction=YFractions[model]; // smeru obou os
iterations=MaxIterations[model]; // ziskat maximalni pocet iteraci
startIterations=StartIterations[model]; // ziskat pocet startovnich iteraci
activeVertexes=MaxVertexes[model]; // ziskat index aktivniho vertexu
filterType=Filters[model]; // ziskat index vybraneho filtru
for (int i=0; i<8; i++) { // smycka pres vsechny vertexy
vertexX[i]=Vertexes[model][i*2]; // kopie hodnot
vertexY[i]=Vertexes[model][i*2+1];
}
for (int j=0; j<8; j++) { // kopie hodnot prvnu z matice
for (int i=0; i<8; i++) { // posloupnosti transformaci
restrictions[j][i]=Restrictions[model][i+(j<<3)]!=0;
}
}
choiceVertexes.select(activeVertexes-3); // nastaveni list-boxu
choiceFilter.select(filterType);
scrollBarIterations.setValue(iterations); // nastaveni slideru
scrollBarStartIterations.setValue(startIterations);
scrollBarXFraction.setValue((int)(xFraction*1000.0));
scrollBarYFraction.setValue((int)(yFraction*1000.0));
labelIterations.setText("Iterations: "+String.valueOf(iterations));// nastaveni textovych navesti
labelStartIterations.setText("Start iterations: "+String.valueOf(startIterations));
labelXFraction.setText("X-fraction "+String.valueOf(xFraction));
labelYFraction.setText("Y-fraction "+String.valueOf(yFraction));
recalcFractal(); // prepocet fraktalu
}
// ------------------------------------------------------------------------
// Tato metoda provadi prekresleni informaci o systemu.
// Metoda je volana z metody paint() pokud je drawingMode==ShowInfo.
// ------------------------------------------------------------------------
private void redrawInfo() {
drawingMode=ShowInfo; // nastavit rezim prekreslovani
Graphics g=panelCenter.getGraphics(); // ziskat graficky kontext
Runtime r=Runtime.getRuntime(); // ziskat objekt s informacemi o aplikaci
g.setColor(Color.white);
g.fillRect(0, TextBegin, DrawingWidth, TextHeight);
g.setColor(Color.blue);
g.drawString("Info", 10, TextBegin+20);
g.setColor(Color.black); // vypsani informaci o pameti
g.drawString("Total memory: "+r.totalMemory(), 10, TextBegin+40);
g.drawString("Free memory: "+r.freeMemory(), 10, TextBegin+60);
}
// ------------------------------------------------------------------------
// Tato metoda provadi prekresleni napovedy.
// Metoda je volana z metody paint() pokud je drawingMode==ShowHelp.
// ------------------------------------------------------------------------
private void redrawHelp() {
drawingMode=ShowHelp; // nastavit rezim prekreslovani
Graphics g=panelCenter.getGraphics(); // ziskat graficky kontext
g.setColor(Color.white);
g.fillRect(0, TextBegin, DrawingWidth, TextHeight);
g.setColor(Color.blue);
g.drawString("Help", 10, TextBegin+20);
g.setColor(Color.black); // vykresleni kratke napovedy
g.drawString("1. select from model list box", 10, TextBegin+40);
g.drawString("2. change vertex position", 10, TextBegin+60);
g.drawString("3. change restriction matrix", 10, TextBegin+80);
g.drawString("4. change global fractal parameters", 10, TextBegin+100);
}
// ------------------------------------------------------------------------
// Tato metoda provadi prekresleni informaci o aplikaci.
// Metoda je volana z metody paint() pokud je drawingMode==ShowAbout.
// ------------------------------------------------------------------------
private void redrawAbout() {
drawingMode=ShowAbout; // zmenit rezim prekreslovani
Graphics g=panelCenter.getGraphics(); // ziskat graficky kontext
g.setColor(Color.white);
g.fillRect(0, TextBegin, DrawingWidth, TextHeight);
g.setColor(Color.blue);
g.drawString("About", 10, TextBegin+20);
g.setColor(Color.red);
g.drawString("LinearIFS version 2.0 Java", 10, TextBegin+40);
g.setColor(Color.black); // vypsani retezcu s informacemi o aplikaci
g.drawString("Author: Pavel Tisnovsky", 10, TextBegin+60);
g.drawString("Idea: Petr Petyovsky", 10, TextBegin+80);
g.setColor(Color.blue);
g.drawString("http://www.root.cz/serialy/fraktaly-v-pocitacove-grafice", 10, TextBegin+100);
}
// ------------------------------------------------------------------------
// Tato metoda provadi prekresleni kresby s navrhem fraktalu.
// Metoda je volana z metody paint().
// ------------------------------------------------------------------------
private void redrawDrawing() {
Graphics g=drawing.getGraphics(); // ziskat graficky kontext
g.clearRect(0, 0, DrawingWidth, DrawingHeight+10); // prekreslit pouze horni cast kresby
g.setClip(0, 0, DrawingWidth, DrawingHeight);// nastaveni orezani
g.setColor(Color.blue);
// kod vykreslujici spojnice vertexu
for (int j=0; j<activeVertexes; j++) { // vykreslit spojnice vertexu
for (int i=0; i<activeVertexes; i++) {
if ((i!=j) && restrictions[i][j]) { // pokud je dana posloupnost transformaci povolena
g.drawLine(vertexX[i], vertexY[i], vertexX[j], vertexY[j]);
}
}
}
// kod vykreslujici vsechny aktivni vertexy
for (int i=0; i<activeVertexes; i++) { // vykreslit vsechny aktivni vertexy
g.setColor(Color.white);
g.fillOval(vertexX[i]-8, vertexY[i]-8, 16, 16);
if (i!=selectedVertex) g.setColor(Color.black);// vybrany vertex vykreslit jinou barvou
else g.setColor(Color.red);// nez ostatni vertexy
g.drawOval(vertexX[i]-8, vertexY[i]-8, 16, 16);
g.drawString(String.valueOf(i), vertexX[i]-3, vertexY[i]+5);// vypsat cisla vertexu
}
// kod vykreslujic informace o fraktalu
g.setColor(Color.green); // informace okolo tabulky s matici posloupnosti transformaci
g.fillRect(60, 303+ImageHeight-256, 10, 10);
g.setColor(Color.red);
g.fillRect(60, 319+ImageHeight-256, 10, 10);
g.setColor(Color.gray);
g.fillRect(60, 319+16+ImageHeight-256, 10, 10);
g.setColor(Color.black);
g.drawRect(60, 303+ImageHeight-256, 10, 10);
g.drawRect(60, 319+ImageHeight-256, 10, 10);
g.drawRect(60, 319+16+ImageHeight-256, 10, 10);
g.drawString("Restriction", 60, 280+ImageHeight-256); // informacni text o matici posloupnosti transformaci
g.drawString("matrix", 60, 296+ImageHeight-256);
g.drawString("on", 80, 312+ImageHeight-256);
g.drawString("off", 80, 328+ImageHeight-256);
g.drawString("not used", 80, 344+ImageHeight-256);
// kod vykreslujici prvky matice posloupnosti transformaci
for (int j=0; j<8; j++) { // vykresleni tabulky s prvky matice posloupnosti transformaci
for (int i=0; i<8; i++) {
g.setColor(Color.gray); // sede pozadi
g.fillRect(i*12+150, j*12+265+ImageHeight-256, 10, 10);
g.setColor(Color.black); // cerny ramecek
g.drawRect(i*12+150, j*12+265+ImageHeight-256, 10, 10);
}
}
// kod pro vykresleni nastavenych prvku matice posloupnosti transformaci
for (int j=0; j<activeVertexes; j++) { // vyplneni policek v tabulce podle zadanych podminek
g.setColor(Color.black);
g.drawString(String.valueOf(j), 140, j*12+265+10+ImageHeight-256);
g.drawString(String.valueOf(j), 152+j*12, 372+ImageHeight-256);
for (int i=0; i<activeVertexes; i++) { // pouze pro aktivni vertexy, ostatni zustanou sede
if (restrictions[i][j]) // nastaveni barvy podle hodnoty prvku
g.setColor(Color.green); // v matici posloupnosti transformaci
else
g.setColor(Color.red);
g.fillRect(i*12+150, j*12+265+ImageHeight-256, 10, 10);// vykresleni policka barvou pozadi
g.setColor(Color.black); // vykresleni okraje cernou barvou
g.drawRect(i*12+150, j*12+265+ImageHeight-256, 10, 10);
}
}
}
// ------------------------------------------------------------------------
// Tato metoda provede prekresleni fraktalu.
// Metoda je volana z funkce paint().
// ------------------------------------------------------------------------
private void redrawFractal() {
Graphics g=panelCenter.getGraphics(); // ziskat graficky kontext
g.drawImage(image, 0, 0, this); // provedeni BitBlt
}
// ------------------------------------------------------------------------
// Tato metoda provede filtraci bitmapy s filtrem typu:
// zadny filtr, pouze kopie bitmapy
// ------------------------------------------------------------------------
private void filterNone() {
int pos=0;
for (int j=0; j<ImageHeight; j++) { // pro vsechny radky bitmapy
for (int i=0; i<ImageWidth; i++) { // pro vsechny pixely na radku
pixelDest[pos]=pixelSrc[pos]; // provest kopii pixelu
pos++;
}
}
}
// ------------------------------------------------------------------------
// Tato metoda provede filtraci bitmapy s filtrem typu:
// rozmazani v bloku 2x2 pixely s vyberem ve tvaru bloku
// ------------------------------------------------------------------------
private void filter2x2smooth() {
int pos=0; // index do zdrojove a cilove bitmapy
int color; // RGBA barvove slozky zakodovane do typu int
int r, g, b; // jednotlive rozkodovane barvove slozky
for (int j=0; j<ImageHeight; j++) // vymazani cilove bitmapy
for (int i=0; i<ImageWidth; i++)
pixelDest[pos++]=0xff<<24; // cerna nepruhledna barva
pos=0;
for (int j=0; j<ImageHeight-1; j++) { // pro vsechny radky bitmapy
for (int i=0; i<ImageWidth-1; i++) { // pro vsechny sloupce na radku bitmapy
color=pixelSrc[pos]; r =(color & 0xff0000)>>16; g =(color & 0x00ff00)>>8; b =(color & 0x0000ff);
color=pixelSrc[pos+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ImageWidth]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ImageWidth+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
r/=4; g/=4; b/=4; // provest filtraci
pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24);
pos++;
}
}
}
// ------------------------------------------------------------------------
// Tato metoda provede filtraci bitmapy s filtrem typu:
// rozmazani v bloku 3x3 pixely s vyberem ve tvaru diamantu
// ------------------------------------------------------------------------
private void filter3x3diamond() {
int pos=0; // index do zdrojove a cilove bitmapy
int color; // RGBA barvove slozky zakodovane do typu int
int r, g, b; // jednotlive rozkodovane barvove slozky
for (int j=0; j<ImageHeight; j++) // vymazani cilove bitmapy
for (int i=0; i<ImageWidth; i++)
pixelDest[pos++]=0xff<<24; // cerna nepruhledna barva
pos=1+ImageWidth;
for (int j=1; j<ImageHeight-1; j++) { // pro vsechny radky bitmapy
for (int i=1; i<ImageWidth-1; i++) { // pro vsechny sloupce na radku bitmapy
color=pixelSrc[pos-ImageWidth]; r =(color & 0xff0000)>>16; g =(color & 0x00ff00)>>8; b =(color & 0x0000ff);
color=pixelSrc[pos-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ImageWidth]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
r/=4; g/=4; b/=4; // provest filtraci
pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24);
pos++;
}
}
}
// ------------------------------------------------------------------------
// Tato metoda provede filtraci bitmapy s filtrem typu:
// rozmazani v bloku 3x3 pixely s vyberem ve tvaru osoveho krize
// ------------------------------------------------------------------------
private void filter3x3cross() {
int pos=0; // index do zdrojove a cilove bitmapy
int color; // RGBA barvove slozky zakodovane do typu int
int r, g, b; // jednotlive rozkodovane barvove slozky
for (int j=0; j<ImageHeight; j++) // vymazani cilove bitmapy
for (int i=0; i<ImageWidth; i++)
pixelDest[pos++]=0xff<<24; // cerna nepruhledna barva
pos=1+ImageWidth;
for (int j=1; j<ImageHeight-1; j++) { // pro vsechny radky bitmapy
for (int i=1; i<ImageWidth-1; i++) { // pro vsechny sloupce na radku bitmapy
color=pixelSrc[pos-ImageWidth]; r =(color & 0xff0000)>>16; g =(color & 0x00ff00)>>8; b =(color & 0x0000ff);
color=pixelSrc[pos-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ImageWidth]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
r/=5; g/=5; b/=5; // provest filtraci
pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24);
pos++;
}
}
}
// ------------------------------------------------------------------------
// Tato metoda provede filtraci bitmapy s filtrem typu:
// rozmazani v bloku 3x3 pixelu s vyberem ve tvaru uhlopricneho krize
// ------------------------------------------------------------------------
private void filter3x3Xcross() {
int pos=0; // index do zdrojove a cilove bitmapy
int color; // RGBA barvove slozky zakodovane do typu int
int r, g, b; // jednotlive rozkodovane barvove slozky
for (int j=0; j<ImageHeight; j++) // vymazani cilove bitmapy
for (int i=0; i<ImageWidth; i++)
pixelDest[pos++]=0xff<<24; // cerna nepruhledna barva
pos=1+ImageWidth;
for (int j=1; j<ImageHeight-1; j++) { // pro vsechny radky bitmapy
for (int i=1; i<ImageWidth-1; i++) { // pro vsechny sloupce na radku bitmapy
color=pixelSrc[pos-ImageWidth-1]; r =(color & 0xff0000)>>16; g =(color & 0x00ff00)>>8; b =(color & 0x0000ff);
color=pixelSrc[pos-ImageWidth+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ImageWidth-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos-ImageWidth+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
r/=5; g/=5; b/=5; // provest filtraci
pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24);
pos++;
}
}
}
// ------------------------------------------------------------------------
// Tato metoda provede filtraci bitmapy s filtrem typu:
// rozmazani v bloku 3x3 pixelu s blokovym vyberem
// ------------------------------------------------------------------------
private void filter3x3block() {
int pos=0; // index do zdrojove a cilove bitmapy
int color; // RGBA barvove slozky zakodovane do typu int
int r, g, b; // jednotlive rozkodovane barvove slozky
for (int j=0; j<ImageHeight; j++) // vymazani cilove bitmapy
for (int i=0; i<ImageWidth; i++)
pixelDest[pos++]=0xff<<24; // cerna nepruhledna barva
pos=1+ImageWidth;
for (int j=1; j<ImageHeight-1; j++) { // pro vsechny radky bitmapy
for (int i=1; i<ImageWidth-1; i++) { // pro vsechny sloupce na radku bitmapy
color=pixelSrc[pos-ImageWidth-1]; r =(color & 0xff0000)>>16; g =(color & 0x00ff00)>>8; b =(color & 0x0000ff);
color=pixelSrc[pos-ImageWidth]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos-ImageWidth+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ImageWidth-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ImageWidth]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos-ImageWidth+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
r/=9; g/=9; b/=9; // provest filtraci
pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24);
pos++;
}
}
}
// ------------------------------------------------------------------------
// Tato metoda provede filtraci bitmapy s filtrem typu:
// rozmazani v bloku 5x5 pixelu s vyberem ve tvaru diamantu
// ------------------------------------------------------------------------
private void filter5x5diamond() {
int pos=0; // index do zdrojove a cilove bitmapy
int color; // RGBA barvove slozky zakodovane do typu int
int r, g, b; // jednotlive rozkodovane barvove slozky
for (int j=0; j<ImageHeight; j++) // vymazani cilove bitmapy
for (int i=0; i<ImageWidth; i++)
pixelDest[pos++]=0xff<<24; // cerna nepruhledna barva
pos=2+2*ImageWidth;
for (int j=2; j<ImageHeight-2; j++) { // pro vsechny radky bitmapy
for (int i=2; i<ImageWidth-2; i++) { // pro vsechny sloupce na radku bitmapy
color=pixelSrc[pos-2*ImageWidth+0]; r =(color & 0xff0000)>>16; g =(color & 0x00ff00)>>8; b =(color & 0x0000ff);
color=pixelSrc[pos- ImageWidth-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos- ImageWidth+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos-2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ ImageWidth-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ ImageWidth+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+2*ImageWidth+0]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
r/=8; g/=8; b/=8; // provest filtraci
pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24);
pos++;
}
}
}
// ------------------------------------------------------------------------
// Tato metoda provede filtraci bitmapy s filtrem typu:
// rozmazani v bloku 5x5 pixelu s vyberem ve tvaru osoveho krize
// ------------------------------------------------------------------------
private void filter5x5cross() {
int pos=0; // index do zdrojove a cilove bitmapy
int color; // RGBA barvove slozky zakodovane do typu int
int r, g, b; // jednotlive rozkodovane barvove slozky
for (int j=0; j<ImageHeight; j++) // vymazani cilove bitmapy
for (int i=0; i<ImageWidth; i++)
pixelDest[pos++]=0xff<<24; // cerna nepruhledna barva
pos=2+2*ImageWidth;
for (int j=2; j<ImageHeight-2; j++) { // pro vsechny radky bitmapy
for (int i=2; i<ImageWidth-2; i++) { // pro vsechny sloupce na radku bitmapy
color=pixelSrc[pos-2*ImageWidth+0]; r =(color & 0xff0000)>>16; g =(color & 0x00ff00)>>8; b =(color & 0x0000ff);
color=pixelSrc[pos- ImageWidth+0]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos-2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ ImageWidth+0]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+2*ImageWidth+0]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
r/=9; g/=9; b/=9; // provest filtraci
pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24);
pos++;
}
}
}
// ------------------------------------------------------------------------
// Tato metoda provede filtraci bitmapy s filtrem typu:
// rozmazani v bloku 5x5 pixelu s vyberem ve tvaru uhlopricneho krize
// ------------------------------------------------------------------------
private void filter5x5Xcross() {
int pos=0; // index do zdrojove a cilove bitmapy
int color; // RGBA barvove slozky zakodovane do typu int
int r, g, b; // jednotlive rozkodovane barvove slozky
for (int j=0; j<ImageHeight; j++) // vymazani cilove bitmapy
for (int i=0; i<ImageWidth; i++)
pixelDest[pos++]=0xff<<24; // cerna nepruhledna barva
pos=2+2*ImageWidth;
for (int j=2; j<ImageHeight-2; j++) { // pro vsechny radky bitmapy
for (int i=2; i<ImageWidth-2; i++) { // pro vsechny sloupce na radku bitmapy
color=pixelSrc[pos-2*ImageWidth-2]; r =(color & 0xff0000)>>16; g =(color & 0x00ff00)>>8; b =(color & 0x0000ff);
color=pixelSrc[pos-2*ImageWidth+2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos- ImageWidth-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos- ImageWidth+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ ImageWidth-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ ImageWidth+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+2*ImageWidth-2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+2*ImageWidth+2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
r/=9; g/=9; b/=9; // provest filtraci
pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24);
pos++;
}
}
}
// ------------------------------------------------------------------------
// Tato metoda provede filtraci bitmapy s filtrem typu:
// rozmazani v bloku 5x5 pixelu s vyberem ve tvaru bloku
// ------------------------------------------------------------------------
private void filter5x5block() {
int pos=0; // index do zdrojove a cilove bitmapy
int color; // RGBA barvove slozky zakodovane do typu int
int r, g, b; // jednotlive rozkodovane barvove slozky
for (int j=0; j<ImageHeight; j++) // vymazani cilove bitmapy
for (int i=0; i<ImageWidth; i++)
pixelDest[pos++]=0xff<<24; // cerna nepruhledna barva
pos=2+2*ImageWidth;
for (int j=2; j<ImageHeight-2; j++) { // pro vsechny radky bitmapy
for (int i=2; i<ImageWidth-2; i++) { // pro vsechny sloupce na radku bitmapy
color=pixelSrc[pos-2*ImageWidth-2]; r =(color & 0xff0000)>>16; g =(color & 0x00ff00)>>8; b =(color & 0x0000ff);
color=pixelSrc[pos-2*ImageWidth-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos-2*ImageWidth+0]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos-2*ImageWidth+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos-2*ImageWidth+2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos- ImageWidth-2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos- ImageWidth-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos- ImageWidth+0]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos- ImageWidth+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos- ImageWidth+2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos-2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ ImageWidth-2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ ImageWidth-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ ImageWidth+0]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ ImageWidth+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ ImageWidth+2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+2*ImageWidth-2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+2*ImageWidth-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+2*ImageWidth+0]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+2*ImageWidth+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+2*ImageWidth+2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
r/=25; g/=25; b/=25; // provest filtraci
pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24);
pos++;
}
}
}
// ------------------------------------------------------------------------
// Tato metoda provede filtraci bitmapy s filtrem typu:
// horizontalni filtr rozmazani tri pixelu
// ------------------------------------------------------------------------
private void filter3pixelsH() {
int pos=0; // index do zdrojove a cilove bitmapy
int color; // RGBA barvove slozky zakodovane do typu int
int r, g, b; // jednotlive rozkodovane barvove slozky
for (int j=0; j<ImageHeight; j++) // vymazani cilove bitmapy
for (int i=0; i<ImageWidth; i++)
pixelDest[pos++]=0xff<<24; // cerna nepruhledna barva
pos=1;
for (int j=0; j<ImageHeight; j++) { // pro vsechny radky bitmapy
for (int i=1; i<ImageWidth-1; i++) { // pro vsechny sloupce na radku bitmapy
color=pixelSrc[pos-1]; r =(color & 0xff0000)>>16; g =(color & 0x00ff00)>>8; b =(color & 0x0000ff);
color=pixelSrc[pos]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
r/=3; g/=3; b/=3; // provest filtraci
pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24);
pos++;
}
}
}
// ------------------------------------------------------------------------
// Tato metoda provede filtraci bitmapy s filtrem typu:
// vertikalni filtr rozmazani tri pixelu
// ------------------------------------------------------------------------
private void filter3pixelsV() {
int pos=0; // index do zdrojove a cilove bitmapy
int color; // RGBA barvove slozky zakodovane do typu int
int r, g, b; // jednotlive rozkodovane barvove slozky
for (int j=0; j<ImageHeight; j++) // vymazani cilove bitmapy
for (int i=0; i<ImageWidth; i++)
pixelDest[pos++]=0xff<<24; // cerna nepruhledna barva
pos=ImageWidth;
for (int j=1; j<ImageHeight-1; j++) { // pro vsechny radky bitmapy
for (int i=0; i<ImageWidth; i++) { // pro vsechny sloupce na radku bitmapy
color=pixelSrc[pos-ImageWidth]; r =(color & 0xff0000)>>16; g =(color & 0x00ff00)>>8; b =(color & 0x0000ff);
color=pixelSrc[pos]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ImageWidth]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
r/=3; g/=3; b/=3; // provest filtraci
pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24);
pos++;
}
}
}
// ------------------------------------------------------------------------
// Tato metoda provede filtraci bitmapy s filtrem typu:
// horizontalni filtr rozmazani peti pixelu
// ------------------------------------------------------------------------
private void filter5pixelsH() {
int pos=0; // index do zdrojove a cilove bitmapy
int color; // RGBA barvove slozky zakodovane do typu int
int r, g, b; // jednotlive rozkodovane barvove slozky
for (int j=0; j<ImageHeight; j++) // vymazani cilove bitmapy
for (int i=0; i<ImageWidth; i++)
pixelDest[pos++]=0xff<<24; // cerna nepruhledna barva
pos=2;
for (int j=0; j<ImageHeight; j++) { // pro vsechny radky bitmapy
for (int i=2; i<ImageWidth-2; i++) { // pro vsechny sloupce na radku bitmapy
color=pixelSrc[pos-2]; r =(color & 0xff0000)>>16; g =(color & 0x00ff00)>>8; b =(color & 0x0000ff);
color=pixelSrc[pos-1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+1]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+2]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
r/=5; g/=5; b/=5; // provest filtraci
pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24);
pos++;
}
}
}
// ------------------------------------------------------------------------
// Tato metoda provede filtraci bitmapy s filtrem typu:
// vertikalni filtr rozmazani peti pixelu
// ------------------------------------------------------------------------
private void filter5pixelsV() {
int pos=0; // index do zdrojove a cilove bitmapy
int color; // RGBA barvove slozky zakodovane do typu int
int r, g, b; // jednotlive rozkodovane barvove slozky
for (int j=0; j<ImageHeight; j++) // vymazani cilove bitmapy
for (int i=0; i<ImageWidth; i++)
pixelDest[pos++]=0xff<<24; // cerna nepruhledna barva
pos=2*ImageWidth;
for (int j=2; j<ImageHeight-2; j++) { // pro vsechny radky bitmapy
for (int i=0; i<ImageWidth; i++) { // pro vsechny sloupce na radku bitmapy
color=pixelSrc[pos-2*ImageWidth]; r =(color & 0xff0000)>>16; g =(color & 0x00ff00)>>8; b =(color & 0x0000ff);
color=pixelSrc[pos- ImageWidth]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+ ImageWidth]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
color=pixelSrc[pos+2*ImageWidth]; r+=(color & 0xff0000)>>16; g+=(color & 0x00ff00)>>8; b+=(color & 0x0000ff);
r/=5; g/=5; b/=5; // provest filtraci
pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24);
pos++;
}
}
}
// ------------------------------------------------------------------------
// Tato metoda zmeni aktualni filtr.
// ------------------------------------------------------------------------
private void applyFilter() {
switch (filterType) {
case 0: filterNone(); break; // zadny filtr
case 1: filter2x2smooth(); break; // filtr typu 2x2 smooth
case 2: filter3x3diamond(); break; // filtr typu 3x3 diamond
case 3: filter3x3cross(); break; // filtr typu 3x3 cross
case 4: filter3x3Xcross(); break; // filtr typu 3x3 X cross
case 5: filter3x3block(); break; // filtr typu 3x3 block
case 6: filter5x5diamond(); break; // filtr typu 5x5 diamond
case 7: filter5x5cross(); break; // filtr typu 5x5 cross
case 8: filter5x5Xcross(); break; // filtr typu 5x5 X cross
case 9: filter5x5block(); break; // filtr typu 5x5 block
case 10: filter3pixelsH(); break; // filtr typu 3 pixels horizontal
case 11: filter5pixelsH(); break; // filtr typu 5 pixels horizontal
case 12: filter3pixelsV(); break; // filtr typu 3 pixels vertical
case 13: filter5pixelsV(); break; // filtr typu 5 pixels vertical
default: break; // tato volba by nemela nikdy nastat
}
}
// ------------------------------------------------------------------------
// Tato metoda provede rozhodnuti, zda je matice posloupnosti
// transformaci korektni pro generovani fraktalu.
// ------------------------------------------------------------------------
private boolean isValidFractal() {
boolean columnOK;
for (int i=0; i<activeVertexes; i++) { // projit vsemi aktivnimi vertexy
columnOK=false;
for (int j=0; j<activeVertexes; j++) // najit alespon jednu povolenou transformaci
if (restrictions[i][j]) columnOK=true;
if (!columnOK) return false; // zadna povolena transformace se nenasla
}
return true;
}
// ------------------------------------------------------------------------
// Tato metoda provede prepocet fraktalu.
// ------------------------------------------------------------------------
private void recalcFractal() {
double xo=5.0, yo=5.0; // stara pozice bodu
double x1, y1, x2, y2; // nova pozice bodu
double xf1, yf1, xf2, yf2; // pomer deleni usecky
int newTransform=0; // transformace
int oldTransform=0;
int x, y;
if (!isValidFractal()) return; // zkontrolovat, zda jsou transformace v poradku
Random r=new Random(0);
for (int i=0; i<ImageWidth*ImageHeight; i++)// smazat obrazek, kam bude fraktal vygenerovan
pixelSrc[i]=0xff << 24;
xf1=xFraction; xf2=1.0-xf1; // vypocet koeficientu deleni usecky
yf1=yFraction; yf2=1.0-yf1;
// vnejsi iteracni smycka
for (int i=0; i<iterations; i++) { // iteracni smycka
// vnitrni smycka pro nalezeni transformace odpovidajici matici posloupnosti transformaci
do { // najit novou transformaci
newTransform=(int)(r.nextDouble()*activeVertexes);
} while (!restrictions[oldTransform][newTransform]);
x1=vertexX[newTransform]; // ziskat polohu vybraneho ridiciho bodu
y1=vertexY[newTransform];
x2=xo;
y2=yo;
xo=x1*xf1+x2*xf2; // vypocet nove pozice bodu
yo=y1*yf1+y2*yf2;
if ((xo>=0) && (xo<=ImageWidth) && // pokud se novy bod nachazi uvnitr obrazku
(yo>=0) && (yo<=ImageHeight) &&
(i>=startIterations)) { // a prekrocili jsme pocet startovnich iteraci
x=(int)xo;
y=(int)yo;
switch (putpixelMode) { // vykreslit novy bod do obrazku
case 0:
pixelSrc[x+y*ImageWidth]=0xffffffff;
break;
case 1:
pixelSrc[x+y*ImageWidth]+=0x00040404;
break;
case 2:
pixelSrc[x+y*ImageWidth]+=0x00080808;
break;
case 3:
pixelSrc[x+y*ImageWidth]+=0x000c0c0c;
break;
case 4:
pixelSrc[x+y*ImageWidth]+=0x00101010;
break;
case 5:
pixelSrc[x+y*ImageWidth]+=0x00141414;
break;
default:
break;
}
}
oldTransform=newTransform;
}
applyFilter(); // aplikace vybraneho filtru
image.flush(); // a vykresleni obrazku na plochu appletu
}
// ------------------------------------------------------------------------
// Tato metoda provede "rychly" prepocet fraktalu - pouze prvnich tisic bodu.
// ------------------------------------------------------------------------
private void recalcFractalQuick() {
double xo=5.0, yo=5.0; // stara pozice bodu
double x1, y1, x2, y2; // nova pozice bodu
double xf1, yf1, xf2, yf2; // pomer deleni usecky
int newTransform=0; // transformace
int oldTransform=0;
int x, y;
if (!isValidFractal()) return; // zkontrolovat, zda jsou transformace v poradku
Random r=new Random(0);
for (int i=0; i<ImageWidth*ImageHeight; i++)// smazat obrazek, kam bude fraktal vygenerovan
pixelDest[i]=0xff << 24;
xf1=xFraction; xf2=1.0-xf1; // vypocet koeficientu deleni usecky
yf1=yFraction; yf2=1.0-yf1;
// vnejsi iteracni smycka
for (int i=0; i<QuickFractalIterations; i++) {// iteracni smycka
// vnitrni smycka pro nalezeni transformace odpovidajici matici posloupnosti transformaci
do { // najit novou transformaci
newTransform=(int)(r.nextDouble()*activeVertexes);
} while (!restrictions[oldTransform][newTransform]);
x1=vertexX[newTransform]; // ziskat polohu vybraneho ridiciho bodu
y1=vertexY[newTransform];
x2=xo;
y2=yo;
xo=x1*xf1+x2*xf2; // vypocet nove pozice bodu
yo=y1*yf1+y2*yf2;
if ((xo>=0) && (xo<=ImageWidth) && // pokud se novy bod nachazi uvnitr obrazku
(yo>=0) && (yo<=ImageHeight) &&
(i>=QuickFractalStartIterations)) { // a prekrocili jsme startovnich iteraci pro "rychle" generovani
x=(int)xo;
y=(int)yo;
pixelDest[x+y*ImageWidth]=0xffffffff;// vykreslit novy bod obrazku
}
oldTransform=newTransform;
}
image.flush(); // vykresleni obrazku na plochu appletu
}
/*
// -----------------------------------------------------------------------
// 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("Linear IFS");
Applet applet=new LinearIFS();
frame.add(applet);
applet.init();
frame.setSize(640, 480);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
);
}
*/
}
// ----------------------------------------------------------------------------
// finito
// ----------------------------------------------------------------------------