Două implementări ale sistemului de funcții iterate
Sistemul de funcții iterate (CIF, sistem de funcții iterați) este un mijloc de obținere a structurilor fractale.
Cel mai simplu CIF constă în transformări afine în plan. (Amintiți-vă că transformările de coordonate afine sunt, în general, o superpoziție de scalare, rotire, traducere paralelă și oglindire.)
În forma generală, transformarea afină în plan este dată de următorul sistem de ecuații:
X '= A * X + B * Y + E
Y '= C * X + D * Y + F
Numărul de sisteme de ecuații utilizate pentru a obține o structură fractală este de cel puțin două. Astfel, pentru a obține o latură fractală (Lattice, Figura 1), sunt luate următoarele patru sisteme:
(1, probabilitatea de selecție este de 0,25)
X '= 0,3 * X - 0,3 * Y + 1
Y '= 0,3 * X + 0,3 * Y + 1
(2, probabilitatea de selecție este de 0,25)
X '= 0,3 * X - 0,3 * Y + 1
Y '= 0,3 * X + 0,3 * Y-1
(3, probabilitatea de selecție este de 0,25)
X '= 0,3 * X - 0,3 * Y - 1
Y '= 0,3 * X + 0,3 * Y + 1
(4, probabilitatea de selecție este de 0,25)
X '= 0,3 * X - 0,3 * Y - 1
Y '= 0,3 * X + 0,3 * Y-1
Fig. 1. Grilaj fractal (construit ca o imagine raster)
Fiecare sistem este numit transformare CIF.
CIF-urile utilizează transformări africane contractive, adică acelea în care factorul de scalare este mai mic decât unul.
Algoritm pentru construirea fractalului CIF:
- Găsiți și pictați punctul de pornire (X, Y) al imaginii (algoritmul pentru găsirea punctului de pornire este prezentat mai jos).
- Selectați una dintre transformările CIF utilizând probabilitățile de selecție cunoscute, găsiți coordonatele (X ', Y') ale noului punct de imagine și vopsiți peste punctul găsit.
- Acceptați X = X 'și Y = Y'.
- Repetați pașii 2 și 3 ale algoritmului, de un număr predeterminat de ori.
Ca punct inițial, puteți lua orice punct care aparține imaginii. Următorul algoritm pentru găsirea punctului de pornire oferă alegerea sa în așa-numitul atractor. adică în zona care aparține imaginii fractalului. Toate punctele ulterioare găsite de algoritmul de mai sus pentru construirea curburii fractale CIF în regiunea atractorului, care nu se mișcă în zone care nu aparțin imaginii.
Algoritmul pentru găsirea punctului de plecare:
- Luați un punct arbitrar (X, Y) în avion.
- Selectați una dintre transformările CIF utilizând probabilitățile de selecție cunoscute și găsiți coordonatele (X ', Y') ale punctului următor.
- Acceptați X = X 'și Y = Y'.
- Repetați pașii 2 și 3 ale algoritmului un număr predeterminat de timp (de exemplu, 100).
- Luați ultimul punct ca punct de plecare.
Luând în considerare fiecare transformare CIF separat, puteți observa că, indiferent de poziția punctului de plecare după mai multe iterații, punctul se oprește în mișcare. Punctul de oprire este numit punct fix.
Conversia punct fix de fiecare parte a atractor. Prin urmare, punctul de plecare pentru construirea de fractale poate lua un punct fix, de exemplu, prima transformare.
CIF poate fi reprezentat mai compact în tabelul următor:
În ultima coloană, pentru fiecare conversie CIF, probabilitatea de selecție este indicată atunci când se caută următorul punct de imagine fractal.
În exemplu, aceste probabilități sunt egale, care, întâmplător, nu sunt tipice.
Codul de mai jos furnizează ieșirea din Fig. 1 a rețelei fractale.
globale ifs, xP, yP, ifsCnt
globale xI, yI, xA, yA
-- Calculează coordonatele următorului punct de imagine fractal
-- Parametrii x și y sunt trecuți prin referință
fn afine col x y = (
t = x * col [1] + y * col [2] + col [5]
y = x * col [3] + y * col [4] + col [6]
x = t
)
-- Găsește punctul de start al imaginii
fn sPoint = (
-- Facem prima transformare CIF
col = pentru k = 1 la 6 colectează dacă [k]
-- După 100 iterații, xP și yP sunt coordonatele punctului de plecare
pentru k = 1 până la 100 nu affine col xP yP
)
-- Alege folosind un generator de numere aleatoare și probabilități de selecție,
-- Transformarea CIF pentru a calcula coordonatele punctului următor al imaginii
fn findK12 K11 k22 = (
-- Obținem un număr aleator din intervalul 0.0 - 1.0
r = aleator 0,0 1,0
p = 0,0
-- j2 - numărul de rânduri din tabelul de transformare CIF
j2 = ifsCnt / 7
j3 = j2 - 1
pentru j = 1 până la j3 (
p + = dacă [7 * j]
dacă r <= p then (j2 = j; exit)
)
-- Indicii de la începutul și sfârșitul rândului selectat al tabelului de transformare CIF
k11 = 7 * (j2-1) + 1
k22 = k11 + 5
)
-- Găsește limitele imaginii fractale și stabilește portul de vizualizare în aceste limite
-- Mai mult, aceste limite sunt folosite pentru a scala imaginea
-- și recalculează coordonatele punctului său actual
fn fConv nPAll = (
local k1, k2
xA = yA = -1e3
xI = yI = 1e3
sPoint ()
pentru k = 1 până la nPAll (
findK12 k1 k2
col = pentru m = k1 la k2 colecta ifs [m]
afine col xP yP
xA = amax # (xP, xA); yA = amax # (yP, yA)
xi = amina # (xP, xi); yI = amina # (yP, yI)
)
viewport.ZoomToBounds fals [xI, 0, yI] [xA, 0, yA]
)
-- Formează o imagine fractală din punctele nPAll
fn showFrctB = (
-- O serie de patru COR-preorazings care definesc o latură fractală
-- Reflectă tabelul CIF-preorazare
ifs # = (0,3, -0.3, 0,3, 0,3, 1, 1, 0,25,
0,3, 0,3, 0,3, 0,3, 1, -1, 0,25,
0,3, -0,3, 0,3, 0,3, -1, 1, 0,25,
0,3, -0,3, 0,3, 0,3, -1, -1, 0,25)
ifsCnt = ifs.Count
-- nPAll - numărul de puncte din imaginea fractală
nPAll = 10000
xP = yP = 1,0
fConv nPAll
bSz = 200
-- Creați o imagine raster de 200 * 200 pixeli
btmp = bitmap bSz bSz culoare: alb
-- Coeficienți pentru recalcularea coordonatelor punctului de imagine
-- Imaginea se încadrează în imaginea bitmap specificată
c = 0,8
cx = c * bSz / (xA-xi)
cy = c * bSz / (yA - y)
d = 0,5 * (1,0-c) * bSz
clr = culoare 0 0 255
k1 = k2 = 0
-- Obțineți puncte de imagine nPAll
-- și le rezolvați sub formă de pixeli albastri ai imaginii raster btmp
-- Originea imaginii bitmap în colțul din stânga sus
pentru k = 1 până la nPAll (
-- Alegem transformarea CIF
findK12 k1 k2
col = pentru m = k1 la k2 colecta ifs [m]
-- Găsiți coordonatele punctului următor al imaginii
afine col xP yP
xb = d + cx * (xP-xi)
yb = bSz - (d + cy * (yP-y))
setPixeluri btmp [xb, yb] # (clr)
)
-- Afișăm rezultatul (vezi Figura 1)
afișați btmp
)
showFrctB ()
Programul este lansat în 3ds Max în următoarea ordine:
Pentru a obține o imagine diferită, este suficient să definiți o matrice ifs cu alte date adecvate. Aceste date pot fi luate din codul din secțiunea "Colecția de particule de flux-fracturi" de mai jos. Deci, dacă matricea ifs este definită de datele celei de-a 8-a cifre
ifs = # (0.824074, 0.281482, -0.212346, 0.864198, -1.882290, -0.110607, 0.787473,
0.088272, 0.520988, -0.463889, -0.377778, 0.785360, 8.095795, 0.212527)
atunci programul va crea o imagine raster a dragonului fractal (Figura 2).
Fig. 2. După înlocuirea matricei ifs
Atunci când se creează un fractal CIF din particulele de particule de flux, capacitățile suplimentare de gestionare a imaginii apar datorită resurselor disponibile în fluxul de particule.
Mai jos este urmat codul care generează o latură CIF de particule cruciforme (Figura 3).
Fig. 3. Grilajul fractal (construit din particule)
Spre deosebire de versiunea anterioară, ieșirea care este executată în handle-ul operatorului particule_flower script_Operator Particle Flow este îndreptată spre portul de vizualizare. În acest caz, se determină poziția particulelor nou create. Poziția particulelor vechi rămâne neschimbată.
Codul, ca și în cazul unei imagini raster, se bazează pe algoritmii de mai sus pentru construirea unei imagini CIF.
global ifs, nPPrev, xP, yP, ifsCnt
-- Pregătirea scenei
funcția tSttngs = (
ștergeți $ *
viewport.SetLayout # layout_4
viewport.ActiveViewport = 2
viewport.SetType #view_front
viewport.SetGridVisibility 2 false
sliderTime = 0f
animationRange = intervalul 0f 50f
timeConfiguration.RealTimePlayback = false
timeConfiguration.PlaybackLoop = false
)
globale ifs, xP, yP, ifsCnt
globale xI, yI, xA, yA
-- Calculează coordonatele următorului punct de imagine fractal
-- Parametrii x și y sunt trecuți prin referință
fn afine col x y = (
t = x * col [1] + y * col [2] + col [5]
y = x * col [3] + y * col [4] + col [6]
x = t
)
-- Găsește punctul de start al imaginii
fn sPoint = (
-- Facem prima transformare CIF
col = pentru k = 1 la 6 colectează dacă [k]
-- După 100 iterații, xP și yP sunt coordonatele punctului de plecare
pentru k = 1 până la 100 nu affine col xP yP
)
-- Alege folosind un generator de numere aleatoare și probabilități de selecție,
-- Transformarea CIF pentru a calcula coordonatele punctului următor al imaginii
fn findK12 K11 k22 = (
-- Obținem un număr aleator din intervalul 0.0 - 1.0
r = aleator 0,0 1,0
p = 0,0
-- j2 - numărul de rânduri din tabelul de transformare CIF
j2 = ifsCnt / 7
j3 = j2 - 1
pentru j = 1 până la j3 (
p + = dacă [7 * j]
dacă r <= p then (j2 = j; exit)
)
-- Indicii de început și de sfârșit al rândului selectat al tabelului de transformare CIF
k11 = 7 * (j2-1) + 1
k22 = k11 + 5
)
-- Găsește limitele imaginii fractale și stabilește portul de vizualizare în aceste limite
-- Mai mult, aceste limite sunt folosite pentru a scala imaginea
-- și recalculează coordonatele punctului său actual
fn fConv nPAll = (
local k1, k2
xA = yA = -1e3
xI = yI = 1e3
sPoint ()
pentru k = 1 până la nPAll (
findK12 k1 k2
col = pentru m = k1 la k2 colecta ifs [m]
afine col xP yP
xA = amax # (xP, xA); yA = amax # (yP, yA)
xi = amina # (xP, xi); yI = amina # (yP, yI)
)
viewport.ZoomToBounds fals [xI, 0, yI] [xA, 0, yA]
)
fn showFrct = (
-- O serie de patru preorazings CIF care definesc o latură fractală
-- Reflectă tabelul CIF-preorazare
ifs # = (0,3, -0.3, 0,3, 0,3, 1, 1, 0,25,
0,3, 0,3, 0,3, 0,3, 1, -1, 0,25,
0,3, -0,3, 0,3, 0,3, -1, 1, 0,25,
0,3, -0,3, 0,3, 0,3, -1, -1, 0,25)
ifsCnt = ifs.Count
-- nPAll - numărul de puncte din imaginea fractală
nPAll local = 10000, emS = 0,8 * 160 * 50
xP = yP = 1,0
fConv nPAll
nPPrev = 1
-- Creați o sursă de particule cu operatori de naștere (naștere)
-- și particule de afișare (DisplayParticles)
-- De asemenea, sursa de particule are operatorul script_Operator,
-- asigurând localizarea coordonatelor particulelor nou-născute
pF = PF_Source enable_Particles: true emitter_Type: 0 \
quantity_Viewport: 100 show_Logo: off show_Emitter: off
particleFlow.BeginEdit ()
opBth = naștere emit_Start: 0 emit_Stop: suma emS: nPAll
-- Afișăm în portul de vizualizare o particulă cruciformă (tip = 2)
opDP = afișareParticule de culoare: albastru de tip: 2
opSO = script_Operator continu_Script: "
-- Canale de transmitere a datelor
pe canale Utilizat pCont (
pCont.UseTime = adevărat
pCont.UsePosition = adevărat
)
pentru a continua pCont do (
k1 = k2 = 0
nP = pCont.NumParticles ()
-- Parametrul nPPrev este introdus pentru a reduce căutarea
pentru k = nPPrev la nP (
pCont.ParticleIndex = k
-- Luăm numai particule noi
dacă pCont.ParticleNew face (
-- Alegem transformarea CIF
findK12 k1 k2
col = pentru m = k1 la k2 colecta ifs [m]
-- Găsiți coordonatele particulei (punctul următor al imaginii)
afine col xP yP
pCont.ParticlePosition = [xP, 0, yP]
)
)
nPPrev = nP
) "
evn = eveniment ()
particleFlow.EndEdit ()
EVOLUȚIA OPȚIUNILOR DE EVALUARE
abd.AppendAction opDP
ev.AppendAction opSO
pF.AppendInitialActionList ev
playAnimation ()
)
-- Gătirea scenei
tSttngs ()
-- Construirea unei imagini
showFrct ()
Adăugați acum la fața locului o bombă care explodează pe cel de-al 10-lea cadru, iar explozia durează 25 de cadre:
pb = simetrie PBomb: 0 haos: 10 start_Time: 10f lasts_Pentru: 25f rezistență: 0.1
Pentru a lua în considerare acest lucru, adăugați următoarea instrucțiune Force la sursa de particule:
opFrc = forța force_Space_Warps: # (pb) influența: 25
Următoarea linie de cod este plasată înainte de metoda AppendInitialActionList:
Rezultatul observat este prezentat în Fig. 4.
Fig. 4. Grilă cu bomba (al 40-lea cadru al animației)
Codul de mai jos construiește obiecte fractale bazate pe sistemul de funcții iterate (CIF), precum și seturile fractale ale lui Mandelbrot și Julia (figurile 5 și 6).
Fig. 5. Setul Mandelbrot
Fig. 6. Seturile Giulia
Fig. 7. Gestionarea dialogului
În Fig. 8 prezintă două fracturi CIF construite din particule.
Fig. 8. Fracturile CIF Flake și Arrow
Numărul de exemple de realizări ale imaginii CIF nu se limitează la acestea. În plus, în unele cazuri, puteți controla ordinea ieșirii punctelor de imagine, după ce ați scris anterior coordonatele lor într-o matrice. Apoi, matricea poate fi sortată, de exemplu, cu coordonatele Y și poate efectua o ieșire secvențială a punctelor sortate. Această metodă, în special, este utilizată în lucrarea "Anotimpurile, toamna" a concursului "Pictură vie" pentru a afișa un copac în creștere.