wz

Juliovy množiny (J-set)

Definice Juliových množin

Juliovy množiny jsou vytvářeny (podobně jako Mandelbrotova množina) pomocí jednoduchého dynamického systému, založeného na postupné iteraci funkce komplexní paraboly:

zn+1=zn2+c

kde proměnné zn a c leží v komplexní rovině. Iterační proces začíná probíhat se startovní hodnotou z0, která v případě Juliových množin reprezentuje pozici bodu v komplexní rovině. Komplexní hodnota c je zvolena libovolně a pro všechny počítané body v jednom obrazci zůstává konstatní.
Juliovy množiny jsou definovány jako množiny všech komplexních čísel z0, pro které posloupnost zn nediverguje:


kde Pcn(0) znamená hodnotu zn pro danou konstantu c a z0.

Pro porovnání si uvedeme i definici Mandelbrotovy množiny:

Rozdíl mezi Mandelbrotovou množinou a Juliovými množinami

Mandelbrotova množina je pouze jedna, jelikož při výpočtu je z0 vždy nastaveno na (komplexní) nulu a mění se pouze c v závislosti na pozici počítaného bodu v komplexní rovině.
Juliových množin je naopak nekonečné množství, protože při výpočtu lze libovolně měnit komplexní hodnotu c. Každé hodnotě c odpovídá určitá Juliova množina. Pozici počítaného bodu v komplexní rovině odpovídá hodnota z0. V závislosti na hodnotě c můžeme Juliovy množiny rozdělit do tří typů, jak bude ukázáno v následujícím textu.
Při výpočtu bodů ležících uvnitř Juliových množin se využívá stejná podmínka pro divergenci posloupnosti zn jako při výpočtu bodů ležících uvnitř Mandelbrotovy množiny, tedy: |c|<=|z| a současně |z|>2. Z toho také vyplývá, že má smysl volit jen takové hodnoty c, jejichž velikost je menší než 2.
Jak bude ukázáno na obrázcích, jsou Juliovy množiny středově symetrické (vzhledem k počátku), zatímco Mandelbrotova množina je symetrická okolo horizontální (reálné) osy. Rozdílná symetričnost je způsobena odlišnými počátečními podmínkami při výpočtu.

Vykreslení Juliových množin

Vykreslování Juliových množin probíhá podobným způsobem jako v případě Mandelbrotovy množiny. Každému bodu v komplexní rovině je přiřazena určitá hodnota z0. Pro tuto hodnotu a pro hodnotu c je zjištěno, zda posloupnost zn diverguje či nikoliv. Pokud posloupnost diverguje, bod odpovídající hodnotě z0 neleží uvnitř Juliovy množiny. Pokud naopak posloupnost po zadaném počtu iterací nediverguje (velikost |zn| nepřekročí hodnotu 2), je počítaný bod prohlášen za prvek dané Juliovy množiny. Algoritmus pro zjištění, zda bod leží uvnitř Juliovy množiny, lze zapsat následovně:

1. nastav iter:=0
2. nastav z:=pozice_bodu_v_komplexní_rovině
3. pokud iter<MaxIter prováděj smyčku:
4. nastav z:=z2+c
5. jestliže |z|>2 bod neleží v Juliově množině; konec
6. nastav iter:=iter+1
7. konec smyčky
8. bod leží uvnitř Juliovy množiny; konec

Tento algoritmus lze přepsat do reálného programovacího jazyka, v našem případě do jazyka C. Dále je uvedena funkce pro výpočet všech bodů v určené oblasti komplexní roviny. V této funkci si všimněme skutečnosti, že hodnota c (v programu cx a cy) je pevně daná uživatelem, zatímco počáteční hodnota posloupnosti z (v programu zx a zy) se mění podle polohy testovaného bodu.

/*
* funkce pro vypocet Juliovych mnozin
*/
void CalcJulia (int width,int height, // velikost bitmapy
double xmin,double xmax,// mezni pozice v komplexni rovine
double ymin,double ymax,
double cx, double cy, // pocatecni pozice v komplexni rovine
int maxiter, byte* data)// max. pocet iteraci a vysledna bitmapa
{
int i,j,iter; // pocitadla smycek
double zx,zy,zx2,zy2; // komplexni promenna "z"
double x,y; // pozice v komplexni rovine
byte* p=data; // ukazatel na zapisovany pixel

y=ymin;
for (j=0; j<height; j++) { // pro vsechny radky v bitmape
x=xmin;
for (i=0; i<width; i++) { // pro vsechny sloupce v bitmape
zx=x; zy=y; // nastavit komplexni promennou "z"
iter=0; // vynulovat pocet iteraci

do { // iteracni smycka
zx2=zx*zx; // zx^2
zy2=zy*zy; // zy^2
zy=2.0*zx*zy+cy;
zx=zx2-zy2+cx; // z:=z^2+c
iter++; // zvysit pocet iteraci
} while (iter<maxiter && (zx2+zy2)<4.0);// test na poc. iteraci a bailout

if (iter==maxiter) { // bod je uvnitr mnoziny
*p=0;p++; // -> cerny pixel
*p=0;p++;
*p=0;p++; // kazdy pixel je ulozen ve trech bytech - RGB
}
else { // bod je vne mnoziny
*p=(byte)(iter*20);p++; // -> obarveny pixel
*p=(byte)(iter*20);p++;
*p=(byte)(iter*20);p++;
}
x+=(xmax-xmin)/width; // dalsi bod v komplexni rovine
}
y+=(ymax-ymin)/height;
printf("radek %d, zbyva %d\n",j+1,height-j-1);// vypsani kontrolni zpravy
}
}
Celý program pro výpočet Juliových množin je uveden zde, popř. jako HTML soubor s obarvenou syntaxí. Program vytvoří základní náhled na Juliovu množinu, přičemž lze pomocí konstant CX0 a CY0 změnit tvar Juliovy množiny. Výsledná bitmapa se poté uloží do souboru typu BMP. Na obrázku je ukázka Juliovy množiny vytvořená pomocí výše uvedeného programu. Povšimněte si středové symetrie obrazce.

Předchozí program lze jednoduše rozšířit tak, aby umožňoval vykreslovat libovolný detail z Juliovy množiny. Princip je stejný jako v případě Mandelbrotovy množiny. Zvolí se, ve které pozici leží střed vykreslovaného obrázku a zvětšení popř. zmenšení oproti originálnímu obrazu. Rozšířený program je uveden zde, popř. jako HTML soubor s obarvenou syntaxí. Uživatel může pomocí konstant XPOS a YPOS zvolit střed vykreslovaného obrázku a pomocí konstanty SCALE měřítko. Na obrázku je vidět detail Juliovy množiny vytvořený tímto programem.

Typy Juliových množin

Jak již bylo dříve uvedeno, existuje nekonečné množství Juliových množin, jež se liší hodnotou c, která je použita při výpočtu. Juliovy množiny lze v závislosti na hodnotě c rozdělit na tři typy:

1. Pro některé hodnoty c tvoří body ležící v Juliově množině spojitou oblast, tzn. každé dva body v Juliově množině lze spojit určitou křivkou tak, že celá křivka leží uvnitř Juliovy množiny.
2. Pro jiné hodnoty c jsou jednotlivé body tvořící Juliovu množinu izolovány, tj. v jejich okolí neexistuje další bod, který by ležel v Juliově množině. Taková Juliova množina se nazývá Cantor dust - Cantorův prach
3. Třetí možnost leží na hranici obou předchozích. Body Juliovy množiny sice nejsou vzájemně izolovány, ale netvoří plochu (body na úsečce také nejsou izolovány, ale úsečka má nulovou plochu).

Pro rozhodnutí, jakého typu bude Juliova množina, stačí zjistit, zda hodnota c (resp. její poloha v komplexní rovině) leží uvnitř Mandelbrotovy množiny. Pokud c leží uvnitř Mandelbrotovy množiny, získáme spojitou Juliovu množinu. Pokud c leží vně Mandelbrotovy množiny, vznikne Cantorův prach. Třetí možnost nastane, jestliže c leží přesně na hranici Mandelbrotovy množiny.

Na následujících obrázcích jsou uvedeny všechny tři typy Juliových množin:


Spojitá Juliova množina


Juliova množina na hranici spojitosti


Cantorův prach

Způsoby animace Juliových množin

Juliovy množiny lze animovat v podstatě dvěma způsoby. První způsob jsme si ukázali v předchozím odstavci u animace průletu Mandelbrotovou množinou. Jednalo se o postupnou změnu měřítka popř. polohy středu počítaného obrázku. Program pro výpočet tohoto typu animace je uveden zde, popř. jako HTML soubor s obarvením syntaxe. Změnou konstant XPOS, YPOS, CX0, CY0, FRAMES, SCALE a SCALE_FACTOR se mění tvar Juliovy množiny a detail pohledu. Pomocí zde uvedeného programu byla vytvořena animace průletu Juliovou množinou. Jedná se o soubor typu MPEG 1, který lze přehrát např. ve Windows Media Playeru.

Druhý způsob animace Juliových množin spočívá v tom, že se postupně mění komplexní hodnota c, která určuje tvar výsledné množiny. Pokud budou změny c dostatečně malé, vznikne složením snímků plynulá animace.

Jako příklad je uveden program, který počítá animaci Juliovy množiny tak, že bod c putuje po spirále. Tvar spirály (počet otoček a hustota) se určuje pomocí konstant DELTA_ALFA, DELTA_RADIUS, START_ALFA a START_RADIUS. Počet snímků lze specifikovat konstantou FRAMES.

Pro vytvoření výsledných animací z jednotlivých snímků byl použit program cmpeg, což je softwarový kodek pro MPEG 1 soubory. Výsledné animace lze přehrát např. pomocí Windows Media Playeru, nebo ovládacího prvku Active Movie. Velikost jednotlivých snímků v animaci je 320x240 pixelů a rychlost přehrávání je nastavena na 25 snímků za sekundu.

# první animace (velikost souboru je 1 914 098 byte)
# druhá animace (velikost souboru je 1 061 852 byte)

Více informací získáte ze skvělých článků Pavla Tišnovského například na této URL: http://www.root.cz/clanky/fraktaly-v-pocitacove-grafice-x


Nahoru


Michal Hladik © 2006