La generazione dei punti di una bitmap appartenenti all'
insieme di Mandelbrot, è un problema facilmente parallelizzabile, poiché il calcolo di un singolo punto è del tutto indipendente dagli altri punti.
Così come mostrato dal seguente codice, che sarà la base della nostra soluzione, e che calcola n righe di immagine a partire dalla riga
ydisp. Oltre a tale
parametri, serviranno anche la risoluzione orizzontale e verticale espressa da
hxres e
hyres e il numero massimo di
iterazioni, espresso dal parametro
itermax e da
magnify che rappresenterebbe lo zoom da applicare all'immagine.
...
RGBApixel** mandelbrot(int hxres, int hyres, int itermax, double magnify,int nrows, int ydisp){
double x,xx,y,cx,cy;
int iteration,hx,hy;
RGBApixel** ret=createBuffer(hxres,ysize);
for (hy=ydisp;hy<ydisp+nrows;hy++){ for(hx=0;hx<hxres;hx++) { cx = (((float)hx)/((float)hxres)-0.5)/magnify*3.0-0.7;
cy = (((float)hy)/((float)hyres)-0.5)/magnify*3.0;
x = 0.0; y = 0.0;
for (iteration = 1;iteration < itermax; iteration++) { xx = x * x - y * y + cx;
y = 2.0 * x * y + cy;
x = xx;
if (x * x + y * y > 100.0)
break;
}
if (iteration == itermax) { ret[hy-ydisp][hx]=BLACK;
} else { ret[hy-ydisp][hx]=computeRGBA(iteration, itermax);
}
}
}
return ret;
}
...
Altra funzione importante è
computeRGBA, che preso in input il numero di iterazione in cui è stato generato il punto e il numero di iterazione massima, stabilisce il colore del punto generato, eseguendo i passi definiti nel codice qui riportato.
RGBApixel computeRGB(int iteration, int itermax){
RGBApixel ret;
double colore = (double)iteration/((double)itermax);
colore = colore*360;
int h = (int)colore*5;
int s = 255;
int v = 255;
int f;
ret.Alpha=1;
if( s == 0 ){ ret.Red=ret.Green=ret.Blue=v;
return ret;
}
long p, q, t;
f = ((h%60)*255)/60;
h /= 60;
p = (v * (256 - s))/256;
q = (v * (256 - ((s * f)/256) ))/256;
t = (v * (256 - ((s * (256 - f))/256)))/256;
switch( h ) { case 0:
ret.Red = v;
ret.Green = t;
ret.Blue = p;
break;
case 1:
ret.Red = q;
ret.Green= v;
ret.Blue = p;
break;
case 2:
ret.Red = p;
ret.Green = v;
ret.Blue = t;
break;
case 3:
ret.Red = p;
ret.Green = q;
ret.Blue = v;
break;
case 4:
ret.Red = t;
ret.Green = p;
ret.Blue = v;
break;
default:
ret.Red = v;
ret.Green = p;
ret.Blue = q;
break;
}
return ret;
}
Nel prossimo articolo mostreremo come utilizzare queste due funzioni per realizzare la nostra implementazione parallela del frattale di Mandelbrot.