Fractali pe bază de motive iterate - Facultatea De Matematica...

15
1 Cursul 4 Fractali pe bază de motive iterate Primii fractali studiaţi, mulţimea lui Cantor, pătratul lui Sierpinski, curba lui von Koch, ş.a., au fost construiţi prin repetarea la infinit a unei anumite reguli de generare, prin care o figu- ră iniţială, numită bază, este înlocuită cu o alta, numită motiv, în care se regăseşte de mai multe ori figura de bază, eventual redusă la scară, rotită, simetrizată sau translatată. De exemplu, construcţia pătratului lui Sierpinski se încadrează în această schemă: în fiecare etapă înlocuim fiecare pătrat bază cu câte un motiv format din 8 pătrăţele cu latura micşorată de trei ori. In etapa următoare, fiecare din cele 8 pătrăţele devine bază pentru aplicarea motivului. Analog, construcţia curbei lui von Koch se obţine prin înlocuirea repetată a fiecărui segment vechi cu patru segmente noi, dispuse după un anumit model. Acest procedeu de construcţie este foarte asemănător cu creşterea organismelor vii, unde, de exemplu, fiecare celulă (baza) se divide şi formează alte două celule (motivul). Spre deosebire de fractali, aici numărul de generaţii este finit iar regula de generare se poate schimba pe parcurs. Un alt exemplu îl dau plantele arborescente a căror creştere anuală poate fi modelată cu următoarea regulă de generare: pe fiecare ramură verde apare un nod din care pleacă una sau mai

Transcript of Fractali pe bază de motive iterate - Facultatea De Matematica...

Page 1: Fractali pe bază de motive iterate - Facultatea De Matematica Iasinecula/down_files/fractali2017... · 2017. 3. 14. · Fractali pe bază de motive iterate Primii fractali studiaţi,

1

Cursul 4

Fractali pe bază de motive iterate

Primii fractali studiaţi, mulţimea lui Cantor, pătratul lui Sierpinski, curba lui von Koch,

ş.a., au fost construiţi prin repetarea la infinit a unei anumite reguli de generare, prin care o figu-

ră iniţială, numită bază, este înlocuită cu o alta, numită motiv, în care se regăseşte de mai multe

ori figura de bază, eventual redusă la scară, rotită, simetrizată sau translatată.

De exemplu, construcţia pătratului lui Sierpinski se încadrează în această schemă: în

fiecare etapă înlocuim fiecare pătrat bază cu câte un motiv format din 8 pătrăţele cu latura

micşorată de trei ori. In etapa următoare, fiecare din cele 8 pătrăţele devine bază pentru aplicarea

motivului.

Analog, construcţia curbei lui von Koch se obţine prin înlocuirea repetată a fiecărui

segment vechi cu patru segmente noi, dispuse după un anumit model.

Acest procedeu de construcţie este foarte asemănător cu creşterea organismelor vii, unde,

de exemplu, fiecare celulă (baza) se divide şi formează alte două celule (motivul). Spre deosebire

de fractali, aici numărul de generaţii este finit iar regula de generare se poate schimba pe parcurs.

Un alt exemplu îl dau plantele arborescente a căror creştere anuală poate fi modelată cu

următoarea regulă de generare: pe fiecare ramură verde apare un nod din care pleacă una sau mai

Page 2: Fractali pe bază de motive iterate - Facultatea De Matematica Iasinecula/down_files/fractali2017... · 2017. 3. 14. · Fractali pe bază de motive iterate Primii fractali studiaţi,

2

multe ramuri noi. Partea dintre nodul vechi şi nodul nou se lemnifică şi nu mai participă la gene-

rare.

In continuare prezentăm câteva clase C# care desenază astfel de fractali. In toate exem-

plele date aici baza este un segment iar motivul este format din două sau mai multe segmente. In

fiecare etapă figura este formată din succesiunea segmentelor de bază, ale căror capete sunt

memorate într-o listă de tip ComList.

Toate clasele utilizate sunt dotate cu metoda transforma(ref ComList li) care par-

curge lista primită, reconstinue succesiunea segmentelor de bază ale figurii, aplică pe fiecare

bază motivul şi construieşte o nouă listă cu capetele noilor segmente. In final, lista nouă este

returnată prin referinţă, deci în locul celei vechi.

1. Curba lui von Koch

public class VonKoch : FractalForm

{

static double theta = Math.PI / 6;

static double ro = 0.5 / Math.Cos(theta);

static Complex w = Complex.setRoTheta(ro, theta);

static double lambda = 1 / 3.0;

void transforma(ref ComList li) //VonKoch

{

ComList rez = new ComList();

Complex z1, z2, delta;

//Segmentul z1_z2 este inlocuit cu //z1_zA, zA_zB, zB_zC si zC_z2, unde

//zA=z1 + lambda* (z2 - z1)

//zB=z1 + w * (z2 - z1))

//zC=z1 + (1-lambda) * (z2 - z1).

rez.nextZet = z1 = li.firstZet;

for (z2 = li.nextZet; !li.ended; z2 = li.nextZet)

{

delta = z2 - z1;

rez.nextZet = z1 + lambda * delta;

rez.nextZet = z1 + w * delta;

rez.nextZet = z2 - lambda * delta;

rez.nextZet = z2;

z1 = z2; }

Page 3: Fractali pe bază de motive iterate - Facultatea De Matematica Iasinecula/down_files/fractali2017... · 2017. 3. 14. · Fractali pe bază de motive iterate Primii fractali studiaţi,

3

li = rez;

} void traseaza(ComList li)

{

Complex z1 = li.firstZet;

initScreen();

for (Complex z2 = li.nextZet; !li.ended; z2 = li.nextZet)

{

setLine(z1, z2, Color.Black);

z1 = z2;

}

delaySec(0.5);

}

public override void makeImage()

{ setXminXmaxYminYmax(-1.1, 1.1, -0.5, 1.5);

ScreenColor = Color.White;

PenColor = Color.Black;

ComList fig = new ComList(); //segmentul initial

fig.nextZet = -1;

fig.nextZet = +1;

traseaza(fig);

for (int k = 0; k <= 5; k++)

{ transforma(ref fig);

traseaza(fig);

if (!resetScreen()) return; }

}

}

Page 4: Fractali pe bază de motive iterate - Facultatea De Matematica Iasinecula/down_files/fractali2017... · 2017. 3. 14. · Fractali pe bază de motive iterate Primii fractali studiaţi,

4

2. Curba lui von Koch în pătrat

public class VonKoch4 : FractalForm

{

static Complex i = new Complex(0, 1);

static double theta = Math.PI / 4.1;

static double ro = 0.5 / Math.Cos(theta);

static Complex w = Complex.setRoTheta(ro, theta);

static double lambda = 1 / 2.1;

void transforma(ref ComList li) //VonKoch {

ComList rez = new ComList();

Complex z1, z2, delta;

//Segmentul z1_z2 este inlocuit cu

//z1_zA, zA_zB, zB_zC si zC_z2, unde

//zA=z1 + lambda* (z2 - z1) //zB=z1 + w * (z2 - z1))

//zC=z1 + (1-lambda) * (z2 - z1).

rez.nextZet = z1 = li.firstZet;

for (z2 = li.nextZet; !li.ended; z2 = li.nextZet)

{

delta = z2 - z1;

rez.nextZet = z1 + lambda * delta; rez.nextZet = z1 + w * delta;

rez.nextZet = z2 - lambda * delta;

rez.nextZet = z2;

z1 = z2;

}

li = rez;

}

void traseaza(ComList li)

{ Complex z1 = li.firstZet;

initScreen();

int n = 1;

for (Complex z2 = li.nextZet; !li.ended; z2 = li.nextZet)

{

setLine(z1, z2, getColor(++n / 500));

z1 = z2;

}

}

public override void makeImage()

{

setXminXmaxYminYmax(-0.1, 1.1, -0.1, 1.1);

ScreenColor = Color.White; PenColor = Color.Black;

ComList fig = new ComList(); //patratul initial

fig.nextZet = 0;

fig.nextZet = 1;

fig.nextZet = 1 + i;

fig.nextZet = i;

fig.nextZet = 0;

for (int k = 0; k <= 8; k++)

{

transforma(ref fig);

traseaza(fig);

Page 5: Fractali pe bază de motive iterate - Facultatea De Matematica Iasinecula/down_files/fractali2017... · 2017. 3. 14. · Fractali pe bază de motive iterate Primii fractali studiaţi,

5

if (!resetScreen()) return;

}

}

}

Rezultat pentru lambda = 1 / 2.1 şi theta = Math.PI / 4.1:

Page 6: Fractali pe bază de motive iterate - Facultatea De Matematica Iasinecula/down_files/fractali2017... · 2017. 3. 14. · Fractali pe bază de motive iterate Primii fractali studiaţi,

6

Rezultat pentru lambda = 1 / 2.0 şi theta = Math.PI / 4.0:

Page 7: Fractali pe bază de motive iterate - Facultatea De Matematica Iasinecula/down_files/fractali2017... · 2017. 3. 14. · Fractali pe bază de motive iterate Primii fractali studiaţi,

7

3. Crabul

public class Crab : FractalForm {

static Complex i = new Complex(0, 1);

static double theta = Math.PI / 4.0;

static double ro = 0.5 / Math.Cos(theta);

static Complex w = Complex.setRoTheta(ro, theta);

void transforma(ref ComList li) //Crab

{

ComList rez = new ComList();

Complex z1, z2;

//Segmentul z1_z2 este inlocuit cu z1_zA si zA_z2

//unde zA=z1+w*(z2-z1). rez.nextZet = z1 = li.firstZet;

for (z2 = li.nextZet; !li.ended; z2 = li.nextZet)

{

rez.nextZet = z1 + w * (z2 - z1);

rez.nextZet = z2;

z1 = z2;

}

li = rez;

}

void traseaza(ComList li)

{

Complex z1 = li.firstZet; int n = 1;

initScreen();

setAxis();

for (Complex z2 = li.nextZet; !li.ended; z2 = li.nextZet) {

setLine(z1, z2, getColor(++n / 30));

z1 = z2;

}

Page 8: Fractali pe bază de motive iterate - Facultatea De Matematica Iasinecula/down_files/fractali2017... · 2017. 3. 14. · Fractali pe bază de motive iterate Primii fractali studiaţi,

8

delaySec(0.5);

} public override void makeImage()

{

setXminXmaxYminYmax(-1, 2, -1.5, 1.5);

ScreenColor = Color.White;

PenColor = Color.Black;

ComList fig = new ComList();

//segmentul initial

fig.nextZet = 0;

fig.nextZet = 1;

for (int k = 0; k < 19; k++)

{

transforma(ref fig);

traseaza(fig); if (!resetScreen()) return;

}

}

}

Rezultat:

Page 9: Fractali pe bază de motive iterate - Facultatea De Matematica Iasinecula/down_files/fractali2017... · 2017. 3. 14. · Fractali pe bază de motive iterate Primii fractali studiaţi,

9

4. Dragonul

public class Dragon : FractalForm

{ static Complex i = new Complex(0, 1);

static double theta = Math.PI / 4.0;

static double ro = 0.5 / Math.Cos(theta);

static Complex w1 = Complex.setRoTheta(ro, theta);

static Complex w2 = Complex.setRoTheta(ro, -theta);

void transforma(ref ComList li) //Dragon

{

ComList rez = new ComList();

Complex z1, z2, w;

//Segmentul z1_z2 este inlocuit cu z1_zA si zA_z2

//unde zA=z1+w*(z2-z1) cu w avand in mod

//alternativ valoarea w1 sau w2. int sign = 1;

rez.nextZet = z1 = li.firstZet;

for (z2 = li.nextZet; !li.ended; z2 = li.nextZet)

{

sign *= -1;

w = (sign > 0 ? w2 : w1);

rez.nextZet = z1 + w * (z2 - z1);

rez.nextZet = z2;

z1 = z2;

} li = rez;

}

void traseaza(ComList li)

{

Complex z1 = li.firstZet;

int n = 1;

initScreen();

setAxis();

for (Complex z2 = li.nextZet; !li.ended; z2 = li.nextZet)

Page 10: Fractali pe bază de motive iterate - Facultatea De Matematica Iasinecula/down_files/fractali2017... · 2017. 3. 14. · Fractali pe bază de motive iterate Primii fractali studiaţi,

10

{

setLine(z1, z2, getColor(++n / 30)); z1 = z2;

}

delaySec(0.5);

}

public override void makeImage()

{

setXminXmaxYminYmax(-0.5, 1.5, -1, 1);

ScreenColor = Color.White;

PenColor = Color.Black;

ComList fig = new ComList();

//segmentul initial

fig.nextZet = 0;

fig.nextZet = 1; for (int k = 0; k < 19; k++)

{

transforma(ref fig);

traseaza(fig); if (!resetScreen()) return;

}

}

Page 11: Fractali pe bază de motive iterate - Facultatea De Matematica Iasinecula/down_files/fractali2017... · 2017. 3. 14. · Fractali pe bază de motive iterate Primii fractali studiaţi,

11

5. Arbori

public class Copac : FractalForm

{

static Complex i = new Complex(0, 1);

static double roTrunchi = 0.9;

static double roRam = 0.6;

static double thetaRam = Math.PI / 7;

static Complex omega_stg = Complex.setRoTheta(roRam, thetaRam);

static Complex omega_drp = Complex.setRoTheta(roRam, -thetaRam);

void transforma(ref ComList li) //Copac

{ ComList rez = new ComList();

Complex z0, z1, zV, zA, zB, delta;

for (z0 = li.firstZet; !li.ended; z0 = li.nextZet)

{

z1 = li.nextZet;

zV = z1 + roTrunchi * (z1 - z0);

delta = zV - z1;

zA = z1 + omega_stg * delta;

zB = z1 + omega_drp * delta;

rez.nextZet = z1; rez.nextZet = zA;

rez.nextZet = z1;

rez.nextZet = zV; rez.nextZet = z1;

rez.nextZet = zB;

}

li = rez; }

void traseaza(ComList li)

{

Complex z;

for (z = li.firstZet; !li.ended; z = li.nextZet)

setLine(z, li.nextZet, Color.Black); delaySec(0.2);

}

public override void makeImage()

{

setXminXmaxYminYmax(-1.1, 1.1, 0 - 0.1, 2.1);

ScreenColor = Color.White;

PenColor = Color.Black;

ComList fig = new ComList();

Complex z0 = 0, z1 = 0.37 * i;

fig.nextZet = z0;

fig.nextZet = z1;

initScreen();

traseaza(fig); for (int k = 1; k <= 6; k++)

{

transforma(ref fig);

traseaza(fig); if (!resetScreen()) return;

}

}

}

Page 12: Fractali pe bază de motive iterate - Facultatea De Matematica Iasinecula/down_files/fractali2017... · 2017. 3. 14. · Fractali pe bază de motive iterate Primii fractali studiaţi,

12

Page 13: Fractali pe bază de motive iterate - Facultatea De Matematica Iasinecula/down_files/fractali2017... · 2017. 3. 14. · Fractali pe bază de motive iterate Primii fractali studiaţi,

13

6. Păduri

Pentru ca arborii desenaţi de noi să aibe un aspect cât de cât natural trebuie să adaugăm

mai multă culoare şi, mai ales, să folosim numere aleatoare pentru a adăuga un “zgomot de fond”

în procesul de generare. Iată un rezultat obţinut destul de uşor:

Page 14: Fractali pe bază de motive iterate - Facultatea De Matematica Iasinecula/down_files/fractali2017... · 2017. 3. 14. · Fractali pe bază de motive iterate Primii fractali studiaţi,

14

public class Padure : FractalForm {

static Random nRand = new Random();

static double zar()

{

return nRand.NextDouble();

}

static int zar(int n) {

return nRand.Next(n);

}

void unPom(Complex w0, Complex delta0, int nrEtape, Color colTr, Color colFl)

{ Complex z0, z1, zV, zA, zB, delta, i = new Complex(0, 1);

Color col = colTr;

double roTr1, roTr = 0.8;

double roRam1, roRam = 0.7;

double thetaTr,thetaRam1, thetaRam = Math.PI / 15;

Complex omegaStg, omrgaDrp, omegaTr;

ComList li0 = new ComList();

ComList li1 = new ComList();

li0.nextZet = w0; ;

li0.nextZet = w0 + delta0; ;

setLine(w0, w0 + delta0, col);

for (int k = 1; k <= nrEtape; k++)

{

for (z0 = li0.firstZet; !li0.ended; z0 = li0.nextZet)

{

z1 = li0.nextZet;

roTr1 = roTr + zar() / 10;

thetaTr = (zar() - 0.5) / 5; omegaTr = Complex.setRoTheta(roTr1, thetaTr);

zV = z1 + omegaTr * (z1 - z0);

delta = zV - z1;

roRam1 = roRam + zar() / 5;

thetaRam1 = thetaRam + zar() / 2;

omegaStg = Complex.setRoTheta(roRam1, thetaRam1);

roRam1 = roRam + zar() / 10; thetaRam1 = thetaRam + zar() / 2;

omrgaDrp = Complex.setRoTheta(roRam1, -thetaRam1);

zA = z1 + omegaStg * delta;

zB = z1 + omrgaDrp * delta;

//if (k == kmax) col = Color.Green;

if (zar() < 0.9) {

li1.nextZet = z1;

li1.nextZet = zA;

setLine(z1, zA, col);

Page 15: Fractali pe bază de motive iterate - Facultatea De Matematica Iasinecula/down_files/fractali2017... · 2017. 3. 14. · Fractali pe bază de motive iterate Primii fractali studiaţi,

15

}

if (zar() < 0.95) {

li1.nextZet = z1;

li1.nextZet = zV;

setLine(z1, zV, col);

}

if (zar() < 0.9)

{

li1.nextZet = z1;

li1.nextZet = zB;

setLine(z1, zB, col);

}

}

roTr *= 0.92; li0 = li1;

li1 = new ComList();

if (!resetScreen()) return;

//delaySec(0.2); }

for (z1 = li0.firstZet; !li0.ended; z1 = li0.nextZet)

{

col = colFl;

z1 = li0.nextZet; int ix = getI(z1.Re);

int jy = getJ(z1.Im);

setPixel(Complex.setReIm(getX(ix), getY(jy)), col); setPixel(Complex.setReIm(getX(ix + 1), getY(jy)), col);

setPixel(Complex.setReIm(getX(ix - 1), getY(jy)), col);

setPixel(Complex.setReIm(getX(ix), getY(jy + 1)), col);

setPixel(Complex.setReIm(getX(ix), getY(jy - 1)), col); //if (!resetScreen()) return;

}

if (!resetScreen()) return;

}

public override void makeImage() {

setXminXmaxYminYmax(0, 1, 0, 1);

Complex w0, delta0; Color colTr, colFr;

int nrEtape = 8;

for (int n = 0; n < 100; n++)

{

w0 = Complex.setReIm(zar(), zar() / 2);

delta0 = Complex.setReIm((zar() - 0.5) / 100, 0.05 + zar() / 5);

colTr = getColor(500 + zar(100));

colFr = getColor(600 + zar(100));

if (zar() < 0.2) colFr = getColor(200 + nRand.Next(100));

unPom(w0, delta0, nrEtape, colTr, colFr);

}

} }