Sunteți pe pagina 1din 8

Grafic pe calculator (12.03.

2015) Informatica, anul 1

GpC_C02

Moduri de desenare
Stabilirea modului de desenare a liniilor se stabileste cu funcia:
void setwritemode (int mod);

unde parametrul poate lua una din valorile din prima coloana (sau corespondentele numerice din a
doua coloan).
Nume model
COPY_PUT
XOR_PUT

Valoare
0
1

Descriere
Desenarea presupune suprascrierea a ceea ce este pe ecran.
Desenarea presupune executarea comenzii XOR ntre linie i
ecran. Dou comenzi de desenare succesive va terge linia,
iar ecranul rmne n forma original.

Aceasta acioneaz asupra funciilor: line, lineto, linerel, rectangle i drawpoly.


Pentru circle, n mod normal, aceast setare nu funcioneaz corespunztor.
Exemplu: Desenai un cerc care se propag pe ecran, pn la apsarea unei taste:
#include <graphics.h>
#include <conio.h>
#include <dos.h>
using namespace std;
int main()
{
initwindow(600,400,"Propagare unda",100,100);
setwritemode(XOR_PUT);
setcolor(YELLOW);
setlinestyle(SOLID_LINE,0,3);
int x0=getmaxx()/2, y0=getmaxy()/2; //centrul ecranului
//desenat peste, va sterge
int r = 10;
while (!kbhit()) {//cat timp nu se apasa o tasta
if (r<=200) {//raza cercului curent pana in 200
circle(x0,y0,r); //deseneaza cercul
delay(200);
circle(x0,y0,r); //sterge cercul
r += 10;
}
else //altfel resetez raza la 10 pixeli
r = 10;
}
getch();
closegraph();
return 0;
}

Grafic pe calculator (12.03.2015) Informatica, anul 1

GpC_C02

Manevrarea imaginilor n MODUL GRAFIC BGI


O figur geometric reprezint o mulime de puncte, curbe i suprafee.
Exist trei funcii deosebit de interesante pentru manevrarea figurilor.
unsigned imagesize(int stanga,int sus,int dreapta,int jos);

Calculeaz dimensiunea zonei de memorie video (numrul de octei necesari pentru memorarea
imaginii) corespunztoare poriunii de ecran dreptunghiulare indicate de parametri. Aceast
dimensiune este util pentru alocarea dinamic a unui buffer (tablou de caractere) n care s poat fi
memorat imaginea.
void getimage(int stanga,int sus,int dreapta,int jos,void *buffer);

Copiaz imaginea din memoria video n buffer.


void putimage(int stanga,int sus,void far *buffer,int operator);

Este operaia invers funciei getimage() i este practic echivalent cu afiarea pe ecran a
imaginii salvate n buffer. Aceast funcie ofer posibiliti mult mai interesante prin parametrul
operator, care controleaz modul de afiare a imaginii. Lista operaiilor posibile apare n tabelul
de mai jos.
Nume
COPY_PUT
XOR_PUT
OR_PUT
AND_PUT
NOT_PUT

Valoare
0
1
2
3
4

Descriere
Copiere simpl din buffer.
Sau exclusiv ntre imagini.
Sau ntre imagini.
i ntre imagini
Copiaz inversul (negaia) imaginii din buffer.

S reamintim tabelele de adevr ale tuturor operaiilor logice enumerate n tabelul anterior:
x
0
0
1
1

y
0
1
0
1

x XOR y
0
1
1
0

x
0
0
1
1

y
0
1
0
1

x OR y
0
1
1
1

x
0
0
1
1

y
0
1
0
1

x AND y
1
0
0
1

x
0
1

NOT x
1
0

Salvarea unei imagini i redesenarea ei ntr-o poziie oarecare este doar aplicaia cea mai
banal. Varianta banal este simpla copiere a buffer-ului care conine imaginea n zona de memorie
video corespunztoare poziiei de pe ecran specificat, folosind COPY_PUT. Evident, coninutul
zonei de ecran este nlocuit cu imaginea transferat. Urmtoarele trei operaii corespund combinrii
imaginii existente pe ecran cu imaginea din buffer, prin operaii logice (bit cu bit): sau exclusiv,
sau, i. Operatorul NOT_PUT copiaz coninutul negat al sursei (negativul imaginii).
Exemplu (OZN):
#include <graphics.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <dos.h>
using namespace std;
int raza=20,xcentru=100,ycentru=50,x,y,x1,y1,x2,y2,i;

Grafic pe calculator (12.03.2015) Informatica, anul 1

GpC_C02

unsigned int marime;


char *figura;
void Miscare(int &x, int &y, int lx, int ly)
{
int pas;
pas = rand()%(2*raza); //cu cat se deplaseaza pe orizontala
if (pas%2) pas=-pas; //daca este impar, schimb sensul stanga-dreapta
x += pas;
//se actualizeaza x-ul coltului ferestrei
pas = rand()%raza; //cu cat se deplaseaza pe verticala
if (pas%2) pas=-pas; //daca este impar, schimb sensul sus-jos
y += pas; //se actualizeaza y-ul coltului ferestrei
//obiectul iese din afara ecranului?
if (x+lx-1>getmaxx()-25) //depaseste latura din dreapta
x = getmaxx()-25-lx+1; //il tin in interior
else
if (x<25) x=25; //depaseste latura din stanga
if (y+ly-1>getmaxy()-25) //depaseste marginea din jos
y = getmaxy()-25-ly+1;
else
if (y<25) y=25; //depaseste marginea de sus
}
int main()
{
initwindow(600,400,"OZN",200,100);
srand(time(0)); //initializam generatorul de numere aleatoare
settextjustify(CENTER_TEXT,TOP_TEXT);
settextstyle(TRIPLEX_FONT,HORIZ_DIR,1);
rectangle(25,25,getmaxx()-25,getmaxy()-25);
char s1[]="ANIMATIE PE CALCULATOR";
outtextxy(320,1,s1);

//deseneaza o farfurie zburatoare


ellipse(xcentru,ycentru, 0,360, raza,raza/3+2); //elipsa intreaga
ellipse(xcentru,ycentru-4, 190,357, raza,raza/3);
//jumatatea de jos dintr-o elipsa
line(xcentru+10,ycentru-6,xcentru+10,ycentru-12); //prima antena
circle(xcentru+10,ycentru-12,2); //varful antenei
line(xcentru-7,ycentru-6,xcentru-10,ycentru-12); //a doua antena
circle(xcentru-10,ycentru-12,2); //varful antenei
setfillstyle(SOLID_FILL,LIGHTRED);
floodfill(xcentru+1,ycentru+4,getcolor());
//se umple partea de jos dintre elipse
//citeste imaginea obiectului
//(x1,y1), (x2,y2) sunt colturile dreptunghiului
//in care se incadreaza obiectul
x1 = xcentru-(raza+1); y1 = ycentru-14;
x2 = xcentru+(raza+1); y2 = ycentru+raza/3+3;
marime = imagesize(x1,y1,x2,y2);
figura = (char *) malloc (marime);
getimage(x1,y1,x2,y2,figura);
putimage(x1,y1,figura,XOR_PUT);//sterge obiectul

Grafic pe calculator (12.03.2015) Informatica, anul 1

GpC_C02

//deseneaza cateva stele


for (i=1;i<=1000;i++)
putpixel(rand()%580+25,rand()%(getmaxy()-50)+25,rand()%(MAXCOLORS1)+1);
x = 320; y = 99; //poz.initiala ferestrei in case se afiseaza obiectul
//(coltul stanga-sus de unde incepe desenarea obiectului)
//miscarea obiectului
do
{
putimage(x,y,figura,XOR_PUT); //deseneaza obiectul
delay(100); //datorita primului XOR_PUT nu va sterge stelele
putimage(x,y,figura,XOR_PUT); //sterge obiectul
Miscare(x,y, x2-x1+1,y2+y1+1);
}
while (!kbhit());
closegraph();
free(figura);
return 0;
}

Alte funcii grafice


tergerea ecranul grafic se realizeaz utiliznd culoarea curent a fondului i poziioneaz
cursorul grafic n origine (0, 0), folosind funcia C
void cleardevice(void);

Reamintim c funcia C getcolor() returneaz indexul din tabloul care definete paleta
relativ la culoarea pentru desenare.
Paleta curent poate fi modificat cu funciile setpalette i setallpalette. Prima
funcie se folosete pentru a modifica o culoare din paleta curent i are prototipul:
void setpalette(int index, int cod);

unde
- index este un ntreg din {0,1,,15} i reprezint indexul din tabloul care definete paleta pentru
culoarea care se modific;
- cod este un ntreg din intervalul {0,1,,63} i reprezint codul culorii care o nlocuiete n palet
pe cea veche.
De exemplu, setpalette (DARKGRAY, 45) modific culoarea corespunztoare indicelui
DARKGRAY (adic 8) prin culoarea de cod 45.
Exemplu:
#include<graphics.h>
#include<conio.h>
#include<stdlib.h>
using namespace std;
int main()
{char s[3];
char s2[]="Codul culorii este: ";
struct palettetype paleta;
initwindow(600,400,"Schimbare paleta de culori",200,100);
setbkcolor(LIGHTGRAY); cleardevice();

Grafic pe calculator (12.03.2015) Informatica, anul 1

GpC_C02

setcolor(RED);
setfillstyle(SOLID_FILL,4); //4=RED
bar(getmaxx()/2-100,getmaxy()/2-50,getmaxx()/2+100,getmaxy()/2+50);
getpalette(&paleta); //citeste paleta curenta
for (int i=0;i<64;i++) //culori disponibile pt adaptoare EGA/VGA
{ setpalette(4,i); //se schimba culoarea 4=RED in culoarea i
//afisam codul culorii cu care se schimba
outtextxy(10,10,s2);
setfillstyle(0,BLACK);
bar(170,10,186,18); //sterg val. scrisa anterior
itoa(i,s,10); //convertesc i in sirul s pt a-l folosi in outtextxy
outtextxy(170,10,s);
setfillstyle(SOLID_FILL,4);
bar(getmaxx()/2-100,getmaxy()/2-50,getmaxx()/2+100,getmaxy()/2+50);
if (getch()==27) break; //din "for" se poate iesi cu tasta ESCAPE
}
setpalette(4, paleta.colors[4]); //revine la culoarea originala a lui 4
closegraph();
return 0;
}

Funcia setallpalette permite modificarea simultan a mai multor culori din compunerea
paletei i are prototipul:
void setallpalette(struct palettetype *paleta)

unde palettetype este un tip definit n fiierul graphics.h astfel:


struct palettetype
{ unsigned char size;
unsigned char colors[MAXCOLOR+1];
};
cu size = dimensiunea paletei, iar colors = tablou ale crui elemente au ca valori codurile

componente ale paletei care se definete.


Modificarea paletei curente cu ajutorul funciilor setpalette i setallpalette conduce la
schimbarea corespunztoare a culorilor afiate pe ecran n momentul apelului funciilor respective.
Pentru a determina codurile culorilor componente ale paletei curente se va folosi funcia
getpalette de prototip:
void getpalette(struct palettetype *paleta);

Paleta implicit poate fi determinat folosind funcia getdefaultpalette de prototip:


struct palettetype* getdefaultpalette(void);

Numrul culorilor dintr-o palet poate fi obinut apelnd funcia getmaxcolor de prototip:
int getmaxcolor(void);

Funcia returneaz numrul maxim de culori diminuat cu o unitate. Deci n adaptorul EGA funcia
returneaz valoarea 15.
O alt funcie care determin dimensiunea paletei este funcia getpalettesize cu
prototipul:
int getpalettesize(void);

Grafic pe calculator (12.03.2015) Informatica, anul 1

GpC_C02

Funcia returneaz numrul culorilor componente ale paletei. n cazul adaptorului EGA funcia
returneaz valoarea 16.
Funcia setgraphmode() permite selectarea altui mod grafic pentru driverul instalat, fa
de cel fixat cu initgraph(), terge ecranul i reiniializeaz parametrii sistemului grafic la
valorile noului mod grafic:
void setgraphmode (int gm);

Funcia restorecrtmode() restabilete modul video existent nainte de apelarea funciei


initgraph(), fr a inchide sistemul grafic:
void restorecrtmode();

O aplicaie uzual a celor dou funcii este trecerea din modul grafic n modul text cu
restorecrtmode() i apoi revenirea n modul grafic se setgraphmode(). Aceasta este soluia
recomandat pentru comutarea modurilor.
Exemplu:
#include<graphics.h>
#include<conio.h>
#include<stdio.h>
using namespace std;
int main()
{char numemod[40];
initwindow(600,400,"Mod grafic, mod text", 100,100);
setbkcolor(LIGHTCYAN); cleardevice();
setcolor(BLUE);
//in numemod se pune un sir de caractere pt afisare
sprintf(numemod,"Modul grafic curent este %s",
getmodename(getgraphmode()));
outtextxy(100,100,numemod);
char s1[]="Apasa o tasta.";
outtextxy(100,120,s1);
getch();
//trecem la modul text
restorecrtmode();
puts("Acum suntem in modul text");
puts("Apasa o tasta");
//textul este scris in fereastra din spatele celei grafice
getch();
//revenim la modul grafic
setgraphmode(getgraphmode());
setbkcolor(LIGHTCYAN); cleardevice();
setcolor(BLUE);
char s2[]="Apasa o tasta pentru inchiderea sistemului grafic";
outtextxy(100,140,s2);
getch();
closegraph();
puts("\nSfarsitul programului");
//textul este scris in fereastra din spatele celei Windows BGI
return 0;
}

Grafic pe calculator (12.03.2015) Informatica, anul 1

GpC_C02

O imagine a ntregului ecran este memorat punct cu punct n memoria video ntr-un buffer
de pagina-ecran. Sistemul grafic (EGA, VGA, Hercules) poate avea pn la opt pagini, numerotate
de la 0 la 7, pagina 0 fiind cea implicit. Se poate utiliza orice pagin la alegere. Dei numai o
pagin de ecran se poate afia la un moment dat, poate fi util s se construiasc noi imagini i n
celelalte pagini, care s fie disponibile la nevoie pentru vizualizare imediat. Este posibil ca o
pagin de ecran s fie vizibil pe ecran, iar funciile de desenare s lucreze cu o alt pagin. Pagina
cu care lucreaz la un momet dat funciile de desenare se numete pagina activ i este fixat cu
funcia:
void setactivepage(int page);

Pagina vizualizat pe ecran se poate specifica folosind funcia:


void setvisualpage(int page);

Pentru a simplifica desenarea figurilor i n general controlul unui ecran ncrcat cu imagini,
este posibil delimitarea unor zone dreptunghiulare, numite viewport, similare cu ferestrele n
modul text. Crearea unui viewport se face cu funcia
void setviewport(int left,int top,int right,int bottom,int clip);

unde
struct viewporttype
{
int left,top,right,bottom,clip;
};

care primete ca parametri coordonatele de ecran ale colurilor opuse stnga-sus i dreapta-jos,
mpreun cu indicatorul clip de tratare a depirii suprafeei ferestrei. Dac parametrul clip are o
valoare nenul, poriunea figurii care nu ncape n fereastr este trunchiat automat. n caz
contrar, figura poate depi limitele ferestrei. La iniializarea sistemului grafiec, viewportul este
implicit tot ecranul. Dup definirea unui viewport, coordonatele transmise funciilor de desenare
sunt interpretate relativ la fereastra curent: colul din stnga-sus al ferestrei are poziia (0,0). La un
moment dat exist o singur fereastr activ (ultima care a fost definit). Pentru a lucra succesiv cu
diverse ferestre este suficient ca la ncheierea operaiilor ntr-o fereastr s se defineasc urmtoarea
cu setviewport().
tergerea ferestrei curente i iniializarea poziiei curente n fereastr cu (0,0) se face cu
funcia
void clearviewport();

Este foarte important determinarea dimensiunilor ferestrei curente. De exemplu, o funcie


care deseneaz o numit imagine poate fi scris astfel nct s ajusteze (scaleze) imaginea n funcie
de fereastra n care se deseneaz. n acest scop se folosete funcia:
void getviewportsettings(struct viewporttype *viewport);

Toate coordonatele utilizate n cadrul funciilor grafice sunt considerate n raport cu ferestrele de
afiare stabilite, explicit sau implicit.
Exemplu:
#include<graphics.h>
#include<conio.h>
using namespace std;

Grafic pe calculator (12.03.2015) Informatica, anul 1

GpC_C02

void imagine()
{
struct viewporttype vp;
int dx,dy;
//detereminarea dimensiunilor ferestrei curente
getviewsettings(&vp); dx = vp.right-vp.left+1; dy = vp.bottom-vp.top+1;
//fixeaza parametrii de desenare
setcolor(YELLOW); setlinestyle(SOLID_LINE,0,THICK_WIDTH);
//deseneaza o dreptunghi (aici=paralelipiped fara adancime)
setfillstyle(XHATCH_FILL,LIGHTGREEN);
bar3d(dx/10,dy/10,dx-dx/10,dy-dy/10,0,0);
getch();
//deseneaza o elipsa
setfillstyle(INTERLEAVE_FILL,LIGHTRED);
fillellipse(dx/2,dy/2,dx/5,dy/5);
}
int main()
{
int mx,my,dmx,dmy;
unsigned dimensiuni;
char *figura;
initwindow(600,400,"Exemplu viewport",200,100);
mx=(getmaxx()+1)/2; my=(getmaxy()+1)/2;
dmx=mx-20; dmy=my-20;
//creeaza prima fereastra
setviewport(10,10,mx-11,my-11,1);
//sfert ecran stanga-sus
//evidentiaza ferestra
setfillstyle(SOLID_FILL,LIGHTBLUE);
bar(0,0,dmx-1,dmy-1);
getch();
//deseneaza imaginea
imagine();//in viewportul stabilit
getch();
//salveaza zona centrala a ferestrei
dimensiuni=imagesize(dmx/4,dmy/4,dmx-dmx/4-1,dmy-dmy/4-1);
figura=(char*)malloc(dimensiuni);
getimage(dmx/4,dmy/4,dmx-dmx/4-1,dmy-dmy/4-1,figura);
putimage(dmx/4,dmy/4,figura,XOR_PUT); //sterge imaginea salvata
getch();
//creeaza alta fereastra
setviewport(mx+10,my+10,2*mx-11,2*my-11,1);
//sfert ecran dr-jos
//evidentiaza noua fereastra
setfillstyle(INTERLEAVE_FILL,LIGHTRED);
bar(0,0,dmx-1,dmy-1);
getch();
//copiaza imaginea salvata in noua fereastra
putimage(0,0,figura,COPY_PUT);//sfertul st-sus din noul viewport
putimage(dmx/2,0,figura,OR_PUT);
//sfertul dreapta-sus din noul viewport
putimage(0,dmy/2,figura,AND_PUT);
//sfertul st-jos din noul viewport
putimage(dmx/2,dmy/2,figura,NOT_PUT);
//sfertul dreapta-jos din noul viewport
getch(); closegraph();
return 0;
}

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