Sunteți pe pagina 1din 12

Coninut

Rasterizarea vectorilor
Grafica pe calculator Rasterizarea cercurilor i a elipselor
Generarea suprafeelor definite prin contur sau
Rasterizarea vectorilor i a prin interior
figurilor n spaiu discret Rasterizarea suprafeelor triunghiulare

Victor Moraru Prezentare realizat n baza materialelor didactice elaborate


victor.moraru@utm.md de ctre doamna prof.univ.dr.ing. Florica Moldoveanu

- Primitivele geometrice (linii, cercuri, poligoane) sunt definite intr-un plan analogic, XOY,
prin coordonate.
-Suprafata de afisare este un spatiu discret, alcatuit din celule de afisare (pixeli) adresate

prin coordonate intregi, (0,0) <= (x,y) <= (xmax,ymax)


Pentru afisare, este necesara descompunerea primitivelor in fragmente care se
afiseaza in celulelele suprafetei de afisare.
afisare
Rasterizarea = operatia prin care o primitiva grafica este descompusa in fragmente

= aproximarea in spatiul discret a unei primitive definite analitic


Un vector este definit analitic prin coordonatele extremitatilor sale : (x1,y1) (x2,y2)

Rasterizarea unui vector = determinarea pixelilor spatiului discret care sunt cei mai
apropiati de vectorul analitic.
1 2




Ecuatia unui vector: y = m*x + b
m = (y2-y1)/(x2-x1) i b=y1 - m*x1 - Tine cont de panta vectorului
Fie: - Coordonatele pixelilor de pe traseul vectorului se obtin printr-un calcul incremental (eficient)
culoare : culoarea in care se afiseaza fragmentele care alcatuiesc vectorul
putpixel(x,y, culoare);// scrie culoarea in celula din memoria imagine(frame buffer), corespunzatoare Fie (x, y) si (x,y) - 2 puncte succesive de pe vector
pixelului de adresa (x,y) - (y y) / (x x ) = (y2 y1) / (x2 x1) = m
|m <1| : incrementare x : x = x +1 y = y + m
Afisarea vectorului: | m >1| : incrementare y: y = y + 1 x = x +1/m
putpixel(x1,y1, culoare);
for(x=x1+1; x<x2; x++)
{ y=m*x+b ; void DDA(int x1, int y1, int x2, int y2, int culoare)
putpixel(x, (int)(y+0.5),culoare); {double m,r; int x, y;
} if(x1==x2) //vector vertical
putpixel(x2,y2,culoare); {if(y1>y2)
{y=y1; y1=y2; y2=y;}
Dezavantaje algoritm : for(y=y1; y<=y2;y++)
Nu se tine cont de panta dreptei: vectorii cu panta mare sunt aproximati prin cativa pixeli! putpixel(x1,y,culoare);
Calculul fiecarei adrese de pixel de pe traseul vectorului contine operatii cu numere reale return;
}
3 4


if(y1==y2) //vector orizontal




{if(x1>x2)


{x=x1; x1=x2; x2=x;}
for(x=x1; x<= x2; x++) putpixel(x,y1,culoare);
return; Contine numai operatii cu numere intregi
} Calcul incremental al coordonatelor pixelilor de pe traseul vectorului
m=(double)(y2-y1)/(x2-x1); r=abs(m);
Pentru fiecare valoare a lui x se alege acel punct al spaiului discret care este mai apropiat
// se genereaza vectorul de la (x1,y1) la (x2,y2)
if(r<=1 && x1>x2 || r>1 && y1>y2) de punctul de pe vectorul teoretic
{x=x1; x1=x2; x2=x; y=y1; y1=y2; y2=y;}
putpixel(x1,
p p ( , yy1,, culoare);); Dezavantaj: calcule cu numere reale Fie m=(y2-y1)/(x2-x1) panta vectorului,
if( r<=1)
(xi, yi) ultimul punct al spaiului discret ales n procesul de generare a vectorului.
for(x=x1+1, r=y1; x<x2; x++)
{r+=m; putpixel(x, (int)(r+0.5), culoare); } // y = y + m d1 distana de la punctul de pe vectorul teoretic, (xi+1, y), la punctul O(xi+1,yi)
else d2 distana de la punctul de pe vectorul teoretic la punctul D(xi+1,yi+1).
{m=1/m; O si D sunt adrese de pixeli (puncte ale spatiului discret)
for(y=y1+1, r=x1; y<y2; y++)
Urmtorul punct al spatiului discret ales pentru aproximarea vectorului va fi:
{r+=m; putpixel((int)(r+0.5), y, culoare); } // x = x +1/m
} - O dac d1<d2, D n caz contrar.
putpixel(x2, y2, culoare); - Dac d1=d2 se poate alege oricare dintre cele dou puncte.
}
5 6



Exprimm diferea d1-d2: ti=(d1-d2)*dx (dx>0)


Deplasament D (diagonal)
(1) Dac ti <= 0, se alege punctul O, deci xi+1 = xi+1 i yi+1 = yi
y=m*(xi+1)+b este ordonata punctului de pe vectorul teoretic
Rezult:
d1=y-yi=m*(xi+1)+b-yi ti+1 = 2*dy*(xi+1) - 2*dx*yi + 2*b*dx - dx +2*dy
d2=yi+1-y=yi+1-m*(xi+1)-b sau ti+1 = ti +2*dy Deplasament O (orizontal)

d1-d2=2*m*(xi+1)-2*yi+2*b -1 (2) Dac ti > 0, se alege punctul D, deci xi+1 = xi + 1 i yi+1 = yi +1


Rezult:
Se nlocuiete m cu dy/dx apoi se nmulete n ambele pri cu dx. Rezult:
ti+1 = 2*dy*(xi+1) - 2*dx*(yi+1) + 2*b*dx - dx +2*dy
ti=(d1-d2)*dx=2*dy*(xi+1)-2*dx*yi+2*b*dx-dx =
sau ti+1 = ti + 2*dy - 2*dx
2*dy*xi - 2*dx*yi + 2*b*dx-dx + 2*dy

ti reprezint eroarea de aproximare n pasul i: pe baza sa se alege urmatorul punct al spatiului discret Valoarea variabilei de test se obtine prin calcul incremental: adunarea unei constante intregi

Notm cu (xi+1,yi+1) punctul care se va alege n pasul curent. Eroarea de aproximare pentru primul pas: xi = x1 i yi = y1:
Expresia erorii de aproximare pentru pasul urmtor este: t1 = 2*dy*x1 - 2*dx*y1 + 2*dy dx + 2*dx(y1 - (dy/dx)*x1)
ti+1 = 2*dy*xi+1 - 2*dx*yi+1 + 2*b*dx - dx +2*dy sau t1 = 2*dy-dx

7 8


Implementare in C: Generalizarea algoritmului Bresenham pentru vectori de orice panta

void Bres_vect(int x1, int y1, int x2, int y2, int culoare)
{ //pentru vectori cu panta cuprins ntre 0 i 1 Vectorii definii n spaiul 2D pot fi clasificai, pe baza pantei, n opt clase geometrice,
int dx, c1, c2, x, y, t; numite octani
dx=x2-x1; Un vector care apartine unui octant O are 7 vectori simetrici in ceilalti 7 octanti
c1=(y2-y1)<<1; // 2*dy
c2=c1-(dx<<1); // 2*dy 2*dx octantul 1: dx>0 i dy>0 i dx>=dy;
t 1 d // 2*dy
t=c1-dx; 2*d - dx d
octantul 2: dx>0 i dy>0 i dx<dy;
putpixel(x1, y1, culoare);
for(x=x1+1, y=y1; x<x2; x++) octantul 3: dx<0 i dy>0 i abs(dx)<dy;
{if(t<0) t+=c1; //deplasament O octantul 4: dx<0 i dy>0 i abs(dx)>=dy;
else { t+=c2; y++;} // deplasament D octantul 5: dx<0 i dy<0 i abs(dx)>=abs(dy);
putpixel(x,y,culoare);
octantul 6: dx<0 i dy<0 i abs(dx)<abs(dy);
}
putpixel(x2,y2,culoare); dx=x2 x1 i dy=y2 y1 octantul 7: dx>0 i dy<0 i dx<abs(dy);
} octantul 8: dx>0 i dy<0 i dx>=abs(dy);

9 10






Notam cu: Algoritmul Bresemham generalizat -implementare in C
+h, deplasamentul orizontal spre dreapta (n sensul cresctor al axei x),
void Bres_general(int x1, int y1, int x2, int y2, int culoare)
-h, deplasamentul orizontal spre stnga (n sensul descresctor al axei x),
{ int x, y, i, oct, dx, dy, absdx, absdy, c1, c2, t;
+v, deplasamentul vertical n sus (n sensul cresctor al axei y), if(x1==x2)
-v, deplasamentul vertical n jos (n sensul descresctor al axei y), //vertical
{if(y1>y2){y=y1; y1=y2; y2=y;}
d1, deplasamentul diagonal dreapta-sus,
for(y=y1; y<=y2;y++)
d2, deplasamentul diagonal stnga-sus, putpixel(x1,y,culoare);
return;
t
d3, deplasamentul diagonal stnga-jos,
}
d4, deplasamentul diagonal dreapta-jos. if(y1==y2)
//orizontal
{if(x1>x2) {x=x1; x1=x2; x2=x;}
Octant 1 2 3 4 5 6 7 8 Corespondena ntre alegerea curent ntr-un pas al for(x=x1; x<= x2; x++)
Deplas O +h +v +v -h -h -v -v +h algoritmului Bresenham (punctul O sau punctul D) i putpixel(x,y1,culoare);
Deplas D d1 d1 d2 d2 d3 d3 d4 d4 deplasamentul echivalent n fiecare octant: return;
}

11 12



putpixel(x1,y1,culoare);
for(i=1,x=x1,y=y1; i<absdx; i++)
dx=x2-x1; dy=y2-y1;
absdx=abs(dx); absdy=abs(dy);
{ if(t<0) // deplasament O
{t+=c1;


if(dx>0)//oct=1,2,7,8
switch(oct)
{if(dy>0)// oct=1,2
{case 1: case 8:x++; break; // +h
if(dx>=dy) oct=1; else oct=2;
case 4: case 5:x--;break; // -h
else
case 2: case 3:y++;break; //+v
if(dx>=absdy) oct=8; else oct=7;
case 6: case 7:y--;break; // -v
}
}
else//3,4,5,6
}
{if(dy>0)// oct=3,4
oct=3 4
else
if(absdx>=dy) oct=4; else oct=3;
{t+=c2 // deplasament D
else
switch(oct)
if(absdx>=absdy) oct=5; else oct=6;
{case 1: case 2: x++;y++;break; // d1
}
case 3: case 4: x--;y++;break; // d2
// Numrul de pai la execuia algoritmului generalizat este maxim(abs(dx), abs(dy))
case 5: case 6: x--;y--;break; // d3
// Dac abs(dy) > abs(dx), se inverseaz rolul variabilelor dx i dy n calculul constantelor c1 i c2
case 7: case 8: x++;y--;break; // d4
if(absdy>absdx) // adresele de pe traseul vectorului se obtin prin incrementarea lui y
}
{x=absdx; absdx=absdy;absdy=x;}
}
c1=absdy<<1; c2=c1-(absdx<<1);
putpixel(x,y,culoare);
t=c1-absdx;
13 } putpixel(x2,y2,culoare); 14

}

void Bres_gen(int x1, int y1, int x2, int y2, int ablon)
{ // sablon: intreg pe 16 biti
int val, bit, bii[16] ;
..............................
for(int i=0,val=1; i<16; i++)

{ bii[i] = ablon & val;
val = val << 1;

}
....................................



if(bii[0]]) putpixel(x1,y1,culoare);
for(i=1,x=x1,y=y1, bit=1; i<absdx; i++)
{ .........................................
if(bii[(bit++) % 16]) putpixel(x,y,culoare);





}
if(bii[bit % 16) putpixel(x2,y2,culoare);
}

15 1

2) Folosind ecuatia cercului in coordonate polare


1) Folosind ecuatia cercului in coordonate carteziene x = xc + r* cos(t)
y = yc + r* sint(t) 0 <= t <= 2
(x xc)2 + (y yc)2 = r2
Generarea se reduce la generarea cercului centrat in origine, plus o translatie cu (xc, yc):

Generarea cercului cu centrul in (xc,yc) se reduce la generarea cercului centrat in origine, x = r* cos(t)
plus o translatie cu (xc, yc): y = r* sint(t) 0 <= t <= 2

Cercul poate fi aproximat pintr-o


pintr o polilinie:
x2 + y2 = r2
- daca se calculeaza N puncte de pe cerc, egal distantate, t creste cu pasul 2/N
for x = -r; x< =r; x++)
{ y = (+/ -) sqrt(r2 x2); Calculul punctelor succesive de pe cerc, pe baza unei relatii de recurenta:
putpixel (xc + x, yc + y, culoare); } - (x, y): punctul curent
- (x, y): punctul urmator
Dezavantaje:
x = r* cos(t +pas) = r(cos(t) * cos(pas) sin(t)* sin(pas)) = x*cos(pas) y*sin(pas)
- Spatierea inegala a punctelor de pe cerc afisate
y = r* sin(t + pas) = r(cos(t) * sin(pas) + sin(t)* cos(pas)) = x*sin(pas) + y*cos(pas)
- Calcule complexe cu numere reale

2 3









Avantajul calculului prin recurenta: nu este necesar sa se calculeze sin si cos in fiecare iteratie! Simetria punctelor de pe cerc
// Aproximarea unui cerc printr-o linie poligonala - Fiecare punct de pe cerc are 7 puncte simetrice pe cerc:

void Cerc( int xc, int yc, int r, int N) Este suficient sa se calculeze adresele punctelor dintr-un singur octant al cercului, celelalte puncte

{ double pas = 2*M_PI /N ; //pasul unghiular de pe cerc find calculate prin simetrie

double u, x, y, x1,y1, s, c; // Afiseaza punctele simetrice de pe cerc

c=cos(pas); s=sin(pas); // sin si cos se calculeaza o singura data void punct_simetric(int xc,int yc,int x,int y, int culoare)

for( int i = 1, x=r, y=0; i<N; i++) { putpixel(xc+x,yc+y,culoare);


putpixel(xc+x yc+y culoare);
putpixel(xc+x,yc-y,culoare);
{ x1 =x*c - y*s; // x
putpixel(xc-x,yc-y,culoare);
y1 =x*s + y*c; // y
putpixel(xc-x,yc+y,culoare);
line(xc+(int)(x+0.5), yc+(int)(y+0.5), xc+(int)(x1+0.5), yc+(int)(y1+0.5));
putpixel(xc+y,yc+x,culoare);
x=x1 ; y= y1 ;
} putpixel(xc+y,yc-x,culoare);
line(xc+(int)(x+0.5), yc+(int)(y+0.5),xc+r,yc); putpixel(xc-y,yc-x,culoare);
}
putpixel(xc-y,yc+x,culoare);
4 } 5









- Pentru afisarea punctelor succesive, pasul unghiular trebuie sa fie aprox. (1/ raza). Consideram cercul cu centrul n originea sistemului de coordonate si raza r.

// Calculeaza numai punctele din primul octant si afiseaza toate punctele simetrice In cadrul algoritmului se calculeaza numai punctele din octantul al 2-lea, celelalte
void Cerc_sim( int xc, int yc, int r, int culoare) obtinandu-se prin simetrie.
{ double pas, u, x, y, xx, s, c; Se calculeaza punctele de pe cerc incepand cu (x=0,y=r) pana la (x=y)
pas=1.0/r; // pas unghiular pentru obtinerea de puncte succesive de pe cerc
c=cos(pas); s=sin(pas); Fie (xi,yi) ultimul punct al spatiului discret, ales pentru aproximarea cercului.
putpixel(xc+r,yc,culoare); Urmatorul punct va fi unul dintre (xi+1,yi) si (xi+1,yi-1):
putpixel(xc-r yc culoare);
putpixel(xc-r,yc,culoare);
putpixel(xc,yc+r,culoare); Fie y ordonata punctului de pe cercul teoretic, cu abscisa (xi+1).
putpixel(xc,yc-r,culoare); y2 = r2-(xi+1)2
for(u=pas, x=r, y=0; u<M_PI_4; u+=pas)
Fie d1 si d2 distantele de la cele 2 puncte ale spatiului discret
{ xx=xx; la punctul de pe cercul teoretic.
x =xx*c - y*s;
y =xx*s + y*c;
Intereseaza semnul diferentei (d1-d2): d1 = yi2 - y2 = yi2 - r2 + (xi+1)2
punct_simetric(xc, yc,(int)(x+0.5), (int)(y+0.5), culoare);
} - daca (yi y) > (y- (yi-1)) atunci d2 = y2 - (yi-1)2 = r2 - (xi+1)2 - (yi-1)2
} (yi2 - y2 ) > (y2 - (yi-1)2 )
6 7









Notam cu ti eroarea de aproximare n pasul curent: Valoarea erorii de aproximare n primul pas:
ti = yi2 + 2*(xi+1)2 + (yi-1)2 -2*r2 : x1=0, y1 = r. Rezult, t1 = 3-2*r
ti = d1-d2 = yi2 + 2*(xi+1)2 + (yi-1)2 -2*r2
void Bres_cerc(int xc, int yc, int r, int culoare)
Se obtine o relatie de recurenta pentru calculul erorii de aproximare in pasul urmator: { int x,y,t;
t=3-(r<<1);
ti+1= yi+12 + 2*(xi+1+1)2 + (yi+1-1)2 -2*r2
putpixel(xc+r,yc,culoare); putpixel(xc-r,yc,culoare);
putpixel(xc,yc+r,culoare); putpixel(xc,yc
putpixel(xc,yc-r,culoare);
r,culoare);
(1) Daca ti<0 (d1 < d2) atunci xi+1=xi+1 si yi+1=yi . Deci, for(x=1,y=r; x<y; x++)
{
ti+1= yi2 + 2*((xi+1)+1)2 + (yi-1)2 -2*r2 if(t<0)
t+=6+(x<<2);
sau ti+1 = ti + 4*xi + 6 else
{ t+=10+((x-y)<<2); y--;}
(2) Daca ti >=0 atunci xi+1 = xi + 1 si yi+1 = yi - 1. Deci,
punct_simetric(xc,yc,x,y,culoare);
ti+1 = (yi-1)2 + 2*((xi+1)+1)2 + ((yi-1)-1)2 -2*r2 }
putpixel(xc+x,yc+y,culoare); putpixel(xc+x,yc-y,culoare);
sau ti+1 = ti + 4*(xi - yi) + 10 putpixel(xc-x,yc+y,culoare); putpixel(xc-x,yc-y,culoare);
}
8 9




Ecuaiile parametrice ale elipsei sunt:


EXERCITIU:
x = xc + a*cos(t)
Modificati algoritmul Bresenham pentru generarea cercurilor astfel incat sa se obtina o y = yc + b*sin(t) 0<= t <= 2*
suprafata circulara. unde (xc,yc) este centrul elipsei, iar a si b sunt marimile semiaxelor elipsei.

void Bres_cerc(int xc, int yc, int r, int culoare)


Se poate obine o secven de puncte care aproximeaz circumferina elipsei dndu-i lui t
{ int x,y,t; valori de la 0 la 2 cu un pas constant.
t=3-(r<<1);
Fie (xi,yi) ultimul punct calculat de pe circumferina elipsei:
line(xc yc+r xc yc-r,
line(xc,yc+r,xc, yc r culoare); putpixel(xc-r,yc,culoare);
putpixel(xc r yc culoare); putpixel(xc+r,yc,culoare);
putpixel(xc+r yc culoare);
for(x=1,y=r; x<y; x++) xi = xc + a*cos(t) = xc + a*dx dx=cos(t)
{ yi = yc + b*sin(t) = yc + b*dy dy = sin(t)
if(t<0)
t+=6+(x<<2); Urmtorul punct, (xi+1,yi+1), este distanat de cel curent cu pasul unghiular:
else xi+1 = xc + a*cos(t+pas) = xc + a* dx
{ t+=10+((x-y)<<2); y--;} yi+1 = yc + b*sin(t+pas) = yc + b*dy
line_simetric(xc,yc,x,y,culoare);
dx'=cos(t+pas)=cos(t)*cos(pas) - sin(t)*sin(pas) = dx*c - dy*s
}
putpixel(xc+x,yc+y,culoare); putpixel(xc+x,yc-y,culoare); dy'=sin(t+pas)=cos(t)*sin(pas) + sin(t)*cos(pas) = dx*s + dy*c
putpixel(xc-x,yc+y,culoare); putpixel(xc-x,yc-y,culoare);
} unde c=cos(pas), s=sin(pas) sunt constante
10 11










Rezult: Generarea unei elipse rotite
xi+1 = xc+a*dx = xc + a*(dx*c - dy*s) Fie R, o elips cu centrul n originea sistemului de coordonate i semiaxele a, b rotite cu unghiul u.
yi+1 = yc+b*dy = yc + b*(dx*s + dy*c)
Fie E, elipsa cu centrul n origine i semiaxele a i b suprapuse peste axele sistemului de coordonate.
// Generarea unei elipse cu axele paralele cu axele sistemului de coordonate carteziene 2D
Punctele de pe elipsa R pot fi obinute rotind punctele de pe elipsa E n jurul originii cu unghiul u.
void Elipsa(int xc, int yc, int a, int b, int N)
Dac centrul elipsei R este n (xc,yc), atunci dup rotaie se aplic fiecrui punct translaia cu (xc,yc).
{ double c,s,t,dx,dy,u, pas = 2*M_PI/N; // N: numarul de puncte calculate pe circumferinta elipsei
int x, y, x1, y1 ;
c=cos(pas); s=sin(pas); Fie: x'=
x' a*dx , y'=
y' b*dy punctul curent de pe elipsa E,
E unde vectorul [dx',dy']
[dx' dy'] s-a
s a obinut prin aplicarea
x= xc +a; y = yc; // dx = cos(0) = 1; dy = sin(0) = 0 formulei de recuren.
for(i=1, dx=1, dy=0; i<N; i++)
Notm: dx1=a*dx' , dy1=b*dy
{ t=dx;
Punctul corespunztor de pe elipsa R este:
dx=dx*c - dy*s; // dx
dy=t*s + dy*c; //dy xr = xc + dxr, yr = yc + dyr
x1 = xc +(int)(a*dx+0.5); y1 = yc+(int)(b*dy+0.5); unde (dxr, dyr) se obtin prin rotatia vectorului (dx1,dy1) in jurul originii
line(x, y, x1, y1);
dxr = dx1*cos(u) - dy1*sin(u), dyr = dx1*sin(u) + dy1*cos(u)
x = x1; y = y1;
} line(x, y, xc+a,yc); 12 13
}



// Generarea unei elipse cu axele rotite fata de axele sistemului de coordonate carteziene 2D
void Elipsa_rot(int xc, int yc, int a, int b, int N, double u)
{ double c,s,t,dx,dy,dx1,dy1,cu,su, pas = 2*M_PI/N;
c=cos(pas);s=sin(pas);
cu=cos(u) ;su=sin(u);
x= xc+(int)(a*cu+0.5); y= yc+(int)(a*su+0.5); // punctul initial de pe elipsa rotita

for(i=1, dx=1,dy=0; i< N; i++)
{ t=dx;;

dx=dx*c-dy*s; //dx
dy=t*s+dy*c; // dy
dx1=a*dx; dy1=b*dy; // punctul de pe elipsa nerotita cu centrul in origine
x1 = xc+ (int)(dx1*cu-dy1*su+0.5); y1 = yc + (int)(dx1*su+dy1*cu+0.5);
line(x, y, x1, y1);




x = x1; y = y1;
}
line(x, y, xc+(int)(a*cu+0.5),yc+(int)(a*su+0.5));
}

14 1




Exist dou tipuri de algoritmi folosii la generarea suprafeelor definite prin contur i a celor definite prin
interior:
Suprafetele definite prin contur sau interior sunt suprafete oarecare.
(1) Algoritmi recursivi, bazai pe verificarea culorii punctelor vecine punctului curent (algoritmi flood fill) si

(1) Suprafete definite prin contur modificarea culorii lor pana la atingerea conturului;
- se cunoate culoarea pixelilor care alctuiesc conturul suprafeei i un punct (2) Algoritmi bazai pe parcurgerea liniilor raster care traverseaz suprafaa.
interior;
In algoritmii flood fill se tine cont de tipul suprafetei: conexa de ordin 4 sau conexa de ordin 8:
- la generarea suprafetei conturul trebuie sa fie inscris in memoria imagine;
-ppornind din ppunctul interior cunoscut,, se modific culoarea Fiecare pixel al unei suprafee conexe de ordinul 4 poate fi atins, pornind dintr-un punct interior, printr-

tuturor pixelilor interiori conturului n culoarea i conform ablonului care sunt date. o combinaie de deplasri n numai patru direcii: stnga, dreapta, sus, jos (suprafata a din figura).

Un pixel al unei suprafee conexe de ordinul 8 poate fi atins printr-o combinaie de deplasri orizontale,
(2) Suprafete definite prin interior verticale i diagonale (suprafetele b si c din figura)
- se cunoate culoarea pixelilor interiori suprafeei i un punct interior;
- la generarea suprafetei pixelii sai trebuie sa aiba culoarea data (sa fie inscrisi in
memoria imagine);
- pornind din punctul interior cunoscut, se modific culoarea tuturor pixelilor
suprafeei n culoarea i cu ablonul care sunt date. Suprafete definite prin interior Suprafata definita prin contur



2

3



Consideram suprafata definita prin contur.
Functie de colorare a unei suprafete conexe de ordin 4, definita prin contur.
void sup_conex_4(int x, int y, int cul_interior, int cul_contur) O suprafa poate fi convex sau concav i poate avea guri.
{
int culoare = getpixel(x,y); // se citeste culoarea pixelului (x,y) din memoria imagine Deci, o linie orizontal care o traverseaz poate ntlni conturul suprafeei de mai multe ori:
if(culoare != cul_contur && culoare != cul_interior)
{
putpixel(x,y,cul_interior); // scrie cul_interior pt pixelul (x,y)
sup conex 4(x+1 y,
sup_conex_4(x+1, y cul_interior,
cul interior cul_contur);
cul contur);
sup_conex_4(x -1, y, cul_interior, cul_contur);
sup_conex_4(x, y+1, cul_interior, cul_contur);
sup_conex_4(x, y-1, cul_interior, cul_contur); Un grup compact de pixeli situai pe aceeai linie raster, care nu au culoarea conturului
}
i nici culoarea de umplere, formeaz un interval; de exemplu, E, F i G sunt extremitile
}
Algoritmul necesit un spaiu mare de memorare pentru stiva program. din dreapta a trei intervale de pe aceeai linie raster.

De aceea, pentru generarea suprafeelor definite prin contur sau prin interior sunt Fie I(xi,yi) punctul interior dat. El este primul punct de start pentru colorarea suprafetei.
preferai algoritmii bazai pe parcurgerea liniilor imagine care traverseaza suprafata. Punctele de start pentru colorare se memoreaza intr-o stiva.



4

5


Se introduce in stiva punctul interior dat, I.
Cat timp stiva nu este vida:
(1) Se extrage din vrful stivei punctul de start pentru colorare
(2) Pornind din punctul de start, se coloreaz toi pixelii din dreapta sa pn cnd se
Continutul stivei:
ajunge la contur, apoi toi pixelii din stnga sa pn cnd se ajunge la contur. Se
1. I(xi,yi); se extrage I din stiva;
memoreaz extremitatea dreapt a intervalului colorat, xmax, i extremitatea sa 2. Dupa parcurgerea liniei y = yI si procesarea liniei de deasupra si a celei de dedesubt:
stng xmin.
stng, xmin se adauga
ada ga A(xA,
A( A yA+1),
A+1) (xA,
( A yA-1);
A 1) (xA,
( A yA-1)
A 1) se extrage
e trage in urmatoarea
rmatoarea iteratie
(3) Se examineaz pixelii din intervalul xmin < x < xmax de pe linia de deasupra celei 3. Dupa parcurgerea fiecarei linii din zona 1 (liniile de deasupra sunt deja colorate): se
adauga (xA, y) care se extrage in urmatoarea iteratie
curente, pentru a se determina dac conine numai pixeli de contur sau pixeli deja
4. Dupa parcurgerea primei linii din zona 2: A, B
colorai. Intervalul poate conine mai multe subintervale. Se memoreaz extremitatea
5. Dupa parcurgerea celorlalte linii din zona 2: A, (xB, y); la ultima linie: A, B,C,D
din dreapta a fiecrui subinterval, n stiv.
6. Dupa parcurgerea fiecarei linii din zona 3: A, B, C, (xD, y)
Aceeai prelucrare se execut pentru linia de sub cea curent. 7. Dupa parcurgerea fiecarei linii din zona 4: A, B, C, (xD, y); la ultima linie: A, B, C, E, F, G
Deoarece ultimul punct introdus n stiv este de pe linia 8. Dupa parcurgerea fiecarei linii din zona 5: A, B, C, E, F, (xG, y)
de sub cea curent, prelucrarea se continua cu aceast linie.


6 7

- Colorarea poligonului din figura ncepe din punctul I.

- Dup colorarea liniei y=yI , vor fi colorate liniile din zona 1.


- La prima linie din zona 2 se schimb xmax; la parcurgerea liniei de deasupra sa se memoreaza B

- Atunci cnd se examineaz pixelii de pe linia ce conine latura de sus a

dreptunghiului interior poligonului se vor memora n stiv punctul C i apoi punctul D.



- Punctul D este extras imediat din stiv, devenind punct de start. Parcurgnd linia y=y D , spre

stnga, se va ntlni latura din dreapta a dreptunghiului, modificndu-se xmin.

- Colorarea se continu cu liniile din zona 3, apoi cu cele din zona 4 i din zona 5. Cnd se ajunge

la limita de jos a zonei 5, colorarea nu poate continua nici pe linia de deasupra nici pe cea

de sub ea: nu se adauga punct in stiva

- In iteratia urmatoare punctul din vrful stivei este F, de aceea colorarea se continu cu zona 6,

i aa mai departe. 8 1




1. Se sorteaza varfurile triunghiului crescator dupa coordonata y, a.i. y0 = ymin

Bool SupTri(int x0, int y0, int x1, int y1, int x2, int y2) if( y1 < y0) { t= y1; y1 = y0; y0 =t;}
{ 1. Se sorteaza varfurile triunghiului crescator dupa if( y2 < y0) { t= y2; y2 = y0; y0 =t;}
coordonata y, a.i. y0 = ymin;
2. Daca triunghiul
g este degenerat
g ((varfurile sunt coliniare),
) return false; 2. Daca triunghiul este degenerat (varfurile sunt coliniare), return false

3. Se orienteaza conturul in sens trigonometric (0-1-2: sens trigonometric);


4. Se calculeaza extremitatile segmentelor interioare suprafetei triunghiului, pentru toate
liniile raster de la ymin-triunghi la ymax-triunghi si se memoreaza in 2 tablouri, XMIN, XMAX;
5. Se afiseaza pixelii interiori triunghiului ( intre xmin si xmax pe fiecare linie raster);
return true;
} if(det==0) return false

2 3




3. Se orienteaza conturul in sens trigonometric (0-1-2: sens trigonometric) 4. Se calculeaza extremitatile segmentelor interioare suprafetei triunghiului
xdx0 = x1 x0; dx1 = x2 x0; dy0 = y1 y0; dy1 = y2 y0; Coordonatele xmin, xmax ale extremitatilor segmentelor interioare suprafetei

x1 < x0 , x2 > x0 triunghiului se memoreaza in 2 tablouri:

dx0 < 0, dx1 > 0, dy0 > 0, dy1 > 0 int XMIN[H], XMAX[H]; // H este numarul de linii imagine
det = dx0*dy1- dx1*dy0 < 0 Calculul extremitatilor este efectuat in functiile CalculXmin() si CalculXmax();
sens trigonometric sens trigonometric Cazuri:

CalculXmin(x0, y0,x1, y1);


x1> x0, x2 < x0
dx0>0, dx1<0, dy0>0, dy1>0 CalculXmin(x1, y1, x2, y2);
det = dx0*dy1- dx1*dy0 >0 CalculXmax(x0, y0, x2, y2);
Se inverseaza varful 1 cu 2
sens anti-trigonometric

4 5




CalculXmin(x0, y0, x1, y1); CalculXmin(x0, y0, x1, y1);


CalculXmax(x0, y0, x2, y2); CalculXmax(x0, y0, x2, y2);
CalculXmax(x2, y2, x1, y1);

Calculul coordonatelor xmin, xmax

CalculXmin(x1, y1, x2, y2); m = (y1 - y0)/ (x1 x0) - panta laturii
CalculXmax(x0, y0, x2, y2); (yr +1 yr)/ (xi+1 xi) = m xi+1 = xi + (1/m)
dx = 1.0/m - constanta a laturii
xi+1 = xi + dx calcul incremental

6 7


5. Se afiseaza pixelii interiori triunghiului, intre xmin si xmax pe fiecare linie raster
int XMIN[H], XMAX[H};
ymax = y1; if (y2>y1 )ymax = y2;
void Calcul Xmin(int x0, int y0, int x1, int y1)
{ // y0 < y1 for(int y= y0; y<= ymax; y++)

int y; void CalculXmax(int x0, int y0, int x1, int y1) for( int x = XMIN[y]; x <= XMAX[y]; x++)
if( x0==x1) { - similara cu functia CalculXmin putpixel(x, y, culoare(x,y)); // afisare fragment rezultat din rasterizarea suprafetei
{for(y =y0; y<=y1;y++) - memoreaza punctele
t l succesive
i de l t
d pe latur // triunghiulare
i hi l
XMIN[y] = x0;
return; in tabloul XMAX Functia culoare (int x, int y) calculeaza culoarea fragmentului care se afiseaza in pixelul (x,y),
} }
tinand cont de:
float dx = (float)(x1 x0) / (y1 y0);
- sursele de lumina
XMIN[y0] = x0; XMIN[y1] = x1;
- proprietatile de material ale suprafetei din care face parte triunghiul
for(y = y0 +1; y<y1; y++) - umbre (fragmentul poate fi in umbra)
XMIN[y] = XMIN[y-1] + dx; - ceata
} Functia culoare (int x, int y) este implementata in fragment shader
8 9

S-ar putea să vă placă și