Elemente de grafică în C - tex.tuiasi.ro. dr. mat. Valeria... · se memorează numărul efectiv...

11
PRELEGERE XIV PROGRAMAREA CALCULATOARELOR ŞI LIMBAJE DE PROGRAMARE Elemente de grafică în C I. Moduri video Un număr ridicat de funcţii predefinite video din fişierul antet conio.h şi din biblioteca graphics.lib definesc posibilităţi semnificative pentru utilizarea ecranului în cercetare şi proiectare, în prognozare sau chiar în scopuri comerciale, sub forma clipurilor. În funcţie de destinaţia lor, acestea pot fi împărţite în mai multe categorii, astfel: iniţializare şi instalare mod grafic, tratare erori grafice, desenare linii, trasare cercuri, arcuri şi alte curbe, desenare poligoane şi haşurări, desenare puncte, scriere texte grafice, salvare imagini, definire culori şi definire şi utilizare de ferestre şi de pagini. Pe de o parte, în configuraţiile hardware ale calculatoarelor compatibile IBM PC intervin monitoare de diverse tipuri (monocolor, color sau color extins), iar pe de alta, comunicarea dintre microprocesorul şi monitorul unui calculator nu se face direct, ci prin intermediul memoriei video (memoriei ecran), care se află pe placa adaptorului video (adaptorului grafic), aşa numita placă video (placă grafică, cartelă video, cartelă grafică). Un program de interfaţă (un driver grafic) cu extensia .BGI (Borland Graphics Interface), specific adaptorului folosit, permite controlul interfeţei între funcţiile video prin care microprocesorul depune în memoria video semnale care reprezintă texte şi imagini şi facilităţile oferite de adaptorul grafic, prin care monitorul îşi extrage continuu date din memoria video şi le trimite pe ecran. Dintre cele mai des întîlnite adaptoare video se enumeră: CGA (Color Graphics Adapter), MCGA ( MultiColor Graphics Adapter), EGA (Enhanced Graphics Adapter), EGA64, EGAMono, IBM8514, HGA (Hercules Graphics Adapter), ATT, VGA (Video graphics Array) şi PC3270. Aproape toate adaptoarele grafice pot fi comutate în modurile Hercules, VGA şi EGA, care este şi cel mai vechi. Spre exemplu, adaptoarele grafice EGA şi VGA sînt controlate de driver-ul egavga.bgi. Pentru adaptorul color adresa de început a memoriei ecran este la 0xB800:0, iar pentru cel monocolor la 0xB000:0. Programul 14.1.1 interoghează calculatorul asupra tipului adaptorului video. Rezultatul furnizat a fost adresa 0xB800, adică calculatorul pe care s-a rulat acest program are un adaptor video color. #include <stdio.h> #include <conio.h> #include <graphics.h> #include <stdlib.h> int placa(void) void main() { long incepecran; clrscr(); placa; printf("incepecran = %0x", incepecran); getch(); } int placa(void); int driver, modus; 1

Transcript of Elemente de grafică în C - tex.tuiasi.ro. dr. mat. Valeria... · se memorează numărul efectiv...

Page 1: Elemente de grafică în C - tex.tuiasi.ro. dr. mat. Valeria... · se memorează numărul efectiv de caractere citite, care poate să fie cel mult egal cu 4. lungimea declarată a

PRELEGERE XIVPROGRAMAREA CALCULATOARELOR ŞI LIMBAJE DE PROGRAMARE

Elemente de grafică în C

I. Moduri videoUn număr ridicat de funcţii predefinite video din fişierul antet conio.h şi din biblioteca graphics.lib definesc posibilităţi semnificative pentru utilizarea ecranului în cercetare şi proiectare, în prognozare sau chiar în scopuri comerciale, sub forma clipurilor. În funcţie de destinaţia lor, acestea pot fi împărţite în mai multe categorii, astfel: iniţializare şi instalare mod grafic, tratare erori grafice, desenare linii, trasare cercuri, arcuri şi alte curbe, desenare poligoane şi haşurări, desenare puncte, scriere texte grafice, salvare imagini, definire culori şi definire şi utilizare de ferestre şi de pagini.Pe de o parte, în configuraţiile hardware ale calculatoarelor compatibile IBM PC intervin monitoare de diverse tipuri (monocolor, color sau color extins), iar pe de alta, comunicarea dintre microprocesorul şi monitorul unui calculator nu se face direct, ci prin intermediul memoriei video (memoriei ecran), care se află pe placa adaptorului video (adaptorului grafic), aşa numita placă video (placă grafică, cartelă video, cartelă grafică). Un program de interfaţă (un driver grafic) cu extensia .BGI (Borland Graphics Interface), specific adaptorului folosit, permite controlul interfeţei între funcţiile video prin care microprocesorul depune în memoria video semnale care reprezintă texte şi imagini şi facilităţile oferite de adaptorul grafic, prin care monitorul îşi extrage continuu date din memoria video şi le trimite pe ecran.

Dintre cele mai des întîlnite adaptoare video se enumeră: CGA (Color Graphics Adapter), MCGA ( MultiColor Graphics Adapter), EGA (Enhanced Graphics Adapter), EGA64, EGAMono, IBM8514, HGA (Hercules Graphics Adapter), ATT, VGA (Video graphics Array) şi PC3270. Aproape toate adaptoarele grafice pot fi comutate în modurile Hercules, VGA şi EGA, care este şi cel mai vechi. Spre exemplu, adaptoarele grafice EGA şi VGA sînt controlate de driver-ul egavga.bgi. Pentru adaptorul color adresa de început a memoriei ecran este la 0xB800:0, iar pentru cel monocolor la 0xB000:0. Programul 14.1.1 interoghează calculatorul asupra tipului adaptorului video. Rezultatul furnizat a fost adresa 0xB800, adică calculatorul pe care s-a rulat acest program are un adaptor video color.#include <stdio.h> #include <conio.h> #include <graphics.h> #include <stdlib.h> int placa(void) void main()

{ long incepecran;clrscr();placa;

printf("incepecran = %0x", incepecran);getch(); }

int placa(void);int driver, modus;

1

Page 2: Elemente de grafică în C - tex.tuiasi.ro. dr. mat. Valeria... · se memorează numărul efectiv de caractere citite, care poate să fie cel mult egal cu 4. lungimea declarată a

driver=DETECT;detectgrapf(driver, modus);printf("Driver-ul grafic are numarul:%d", driver);switch (driver)

{ case 1:case 2:case 3:case 4:case 5:case 6:case 8:case 9: incepecran = 0xb800;

break;case -2:case 7:case 10: incepecran = 0xb000;break;

}return incepecran; }

Programul 14.1.1

Densitatea punctelor care alcătuiesc imaginea (rezoluţia) şi numărul maxim de culori (paleta de culori) permise pe ecranul monitorului sînt două caracteristici importante care rezultă din legătura monitor – adaptor şi care determină modul de operare al adaptoarele video, modul text sau modul grafic. Fiecărui driver îi corespunde cel puţin un mod grafic, prin care se precizează rezoluţia şi paleta de culori. Acestea pot fi aflate din tabele sau prin interogarea calculatorului.

În modul text ecranul este gîndit ca o matrice (25, 43 sau 50 linii şi 80 sau 40 coloane) ale cărei elemente sîn caractere ASCII. Colţul din stînga sus are coordonatele (1,1). Pentru o poziţie oarecare (x, y), abscisa x creşte de la stînga către dreapta şi fixează coloana, iar ordonata y de sus în jos şi fixează linia. În memoria video se rezervă doi octeţi pentru fiecare poziţie din matrice, primul octet conţine codul ASCII al caracterului care ocupă acea poziţie, iar al doilea este octetul atribut, care determină modul de reprezentare al caracterului: normal sau intens luminat, cu subliniere sau clipitor (blinking), iar pentru monitoarele color, care este culoarea fundalului şi care cea a textului. În mod normal, pagina de ecran conţine 25 de rînduri a cîte 80 de coloane, deci colţul din stînga sus este (1, 1), iar colţul din dreapta jos (80, 25). Ceea ce rezultă că în modul text sînt necesari 2000 de octeţi carcter şi 2000 de octeţi atribut, deci în total 4000 de octeţi.

În modul grafic, ecranul este descris tot ca o matrice ale cărei elemnte sînt puncte individuale, numite pixeli. Colţul din stînga sus are coordonatele (0,0). Un număr de 8 pixeli pot fi trataţi ca un octet, unde un bit setat înseamnă pixel luminos, iar unul şters pixel întunecat. Imaginea pe ecran este o mulţime de pixeli luminoşi şi coloraţi într-un anume fel. De exemplu, pentru Hercules pagina de ecran cuprinde 348 de rînduri, iar un rînd are 720 de pixeli, (în mod echivalent, 90 de octeţi). Ceea ce

2

Page 3: Elemente de grafică în C - tex.tuiasi.ro. dr. mat. Valeria... · se memorează numărul efectiv de caractere citite, care poate să fie cel mult egal cu 4. lungimea declarată a

înseamnă că este nevoie de multă memorie, adică 348x90=31320 octeţi sau 32ko per pagina de ecran. Înălţimea unui rînd de ecran este de un pixel, pe cînd în modul text este de 8 sau 9 pixele. Grafica în culori, în schimb, necesită mai multă memorie. Cu un bit de pixel pot fi reprezentate maxim două culori, cu doi biţi de pixeli cel mult patru culori, numărul biţilor crescînd rapid în funcţie de numărul culorilor folosite. Zona de memorie necesară se alocă din RAM-ul adaptorului grafic, deoarece în memoria ecran operativă au loc doar două pagini de ecran la adresele 0xB000:0 şi respectiv 0xB800:0. De exemplu, codificarea numerică a paletei de culori implicită pentru VGA: black, blue, green, cyan, red, magenta, brown, white, gray, light_blue, light_green, light_cyan, light_red, light_magenta, yellow, light_white, în ordine, este precizată în lista (0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63). Culoarea de fond (background) este 0, iar culoare cernelii (foreground) este 63. Indicele culorii din paletă se denumeşte prin valoare pixel.

Un concept comun celor două stiluri de lucru îl reprezintă fereastra, care se defineşte prin porţiunea rectangulară de ecran activă la un moment dat. Fereastra poartă denumirea de window pentru modul grafic şi viewport pentru modul grafic. Fereasatra implicită se consideră întreg ecranul. Scrierea textelor sau desenarea imaginilor se face în fereastra curentă, restul ecranului rămînînd nefolosit. Conţinutul ecranului se poate organiza pe mai multe pagini de ecran complete sau numai pe porţiuni de ecran, care pot fi salvate temporar în memoria RAM şi care pot fi apelate succesiv într-un timp scurt, încît să nu se obsrve trecerea de la o pagină la alta.

Placa video şi monitorul pot fi trecute automat la oricare mod în care a fost realizat programul (modul text fiind implicit), atît la nivel PC/MS-DOS prin intermediul funcţiilor realizate de programator, cît şi la nivel DOS SHELL cu ajutorul funcţiilor predefinite video. Modul grafic de lucru, controlul memoriei video, utilizarea culorilor în programe BIOS sau controlul aprinderii şi stingerii cursorului, cu toate că necesită un efort şi cunoştinţe desebite, vor constitui, în cele ce urmează, subiectul unor programe interesante.

II. Modul textModul grafic original de lucru al calculatorului la lansarea în execuţie a unui program este modul text. Funcţiile predefinite aplicabile lucrului în modul text oferă facilităţi pentru controlul ferestrei, scrierea şi modificarea textului cu anumite atibute de culoare, sublinierea şi clipirea unor caractere sau deplasarea, stingerea şi aprinderea cursorului. Aceste funcţii sînt grupate în biblioteca standard şi în plus, pentru fiecare model de memorie există versiuni distincte pentru biblioteca standard.

III. Comutarea în modul textPrototipul funcţiei pentru precizarea modului text de lucru este:

void textmode( int mod_lucru);.Argumentul mod_lucru se stabileşte, în funcţie de tipul adaptorului grafic şi tipul

monitorului cu care este dotat calculatorul, conform tabelului următor:În absenţa argumentului mod_lucru, se subînţeleg parametrii impliciţi ai modului text, adică fereastra activă este tot ecranul, iar afişarea textului se face cu cerneală albă pe fond negru. Comutarea pe modul de lucru anterior, dacă în timpul execuţiei programului s-a schimbat modul de lucru, se face activînd textmode(LASTMODE);. Cu apelările

3

Page 4: Elemente de grafică în C - tex.tuiasi.ro. dr. mat. Valeria... · se memorează numărul efectiv de caractere citite, care poate să fie cel mult egal cu 4. lungimea declarată a

textmode(BW80); şi textmode(2); se descriu rezultate egale, adică un mod text cu 25 de rînduri, 80 de coloane şi afişarea textului în nuanţe de gri.

Denumire simbolică Codul Caracteristici

BW40BW80MONO

CO40CO80LASTMODE

027

13-1

40 x 25 negru/alb pe adaptor color80 x 25 negru/alb pe adaptor color80 x 25 negru/alb pe adaptor monocolor40 x 25 color pe adaptor color80 x 25 color pe adaptor colorModul precedent

Tabelul 14.3.1

IV. Funcţii de intrare/ieşire pentru modul textBiblioteca standard Turbo C++, spre deosebire de cea din C, oferă pentru modul text un ansamblu de funcţii video şi flag-uri (indicatori binari), declarat în conio.h, prin care se realizează operaţii de intrare/ieşire la consolă sub anumite condiţii.Controlul umplerii ferestrei active se efecuează prin setarea flag-ului _wscroll, care este o variabilă globală, pe o valoare întreagă, astfel:

- cu 0 se continuă afişarea textului de la începutul liniei curente, fără saltul la linia următoare;

- cu 1 (valoare implicită), atingerea limitei din dreapta a ferestrei determină continuarea scrierii textului pe linia următoare începînd cu limita dinspre stînga a ferestrei, prin derularea în jos (pe verticală) a textului pentru a face loc noii linii şi dacă este cazul cu ieşirea ultimei linii de pe ecran.

Alegerea modului de scriere pe ecran se deduce din valoarea variabilei globale directvideo:

- cu 0 scrierea se face prin folosirea funcţiilor sistemului de operare (BIOS);- cu 1 (valoare implicită) scrierea se face direct în memoria video. Setarea

variabilei direcvideo pe valoarea implicită impune o creştere substanţială a vitezei de scriere pe ecran.

Nu sînt schimbări esenţiale, în ceea ce priveşte prototipul, absenţa sau prezenţa formatării datelor pe ecran şi modul de efectuare a operaţiilor de citire/scriere, la funcţiile descrise în acest paragraf faţă de cele descrise în paragrafele 5.2.1 – 5.2.4. Numai că orice secvenţă ‘\n’ din şirul de formatare, care descrie saltul la începutul liniei următoare, trebuie să se înlocuiască prin ‘\r\n’.

Returnarea caracterului citit de la tastatură, cu sau fără ecou pe ecran, se descrie prin funcţiile int getche(void); şi respectiv int getch(void);. Tipărirea unui caracter c în fereastra curentă se face cu funcţia: int putch(c);. În caz de eroare, funcţia întoarce EOF.

În mod corespunzător, pentru citirea/scrierea unui şir de caractere se folosesc următoarele: char *cgets(char *s); şi respectiv char *cputs(const char *s);. Cu funcţia cgets() se citeşte şirul de caractere afişat în fereastra curentă pînă la întîlnirea secvenţei ‘\r\n’ sau pînă la satisfacerea lungimii maxime declarate, se depozitează şirul citit la adresa s[2] şi se înscrie marcatorul de sfîrşit de şir de caractere, ‘\0’. La adresa s[1] se memorează numărul efectiv de caractere citite, care poate să fie cel mult egal cu

4

Page 5: Elemente de grafică în C - tex.tuiasi.ro. dr. mat. Valeria... · se memorează numărul efectiv de caractere citite, care poate să fie cel mult egal cu 4. lungimea declarată a

lungimea declarată a şirului de caractere. Lungimea maximă a şirului se înscrie la adresa s[0] înainte de activarea funcţiei cgets(). Deci, dimensiunea şirului de caractere s[] trebuie declarată cu trei octeţi mai mare decît lungimea maximă a acestuia. Rezultatul întors de funcţie este adresa şirului de caractere, adică s+2. La scriere, spre deosebire de funcţia puts(), nu se sare la linie nouă la întîlnirea secvenţei ‘\r\n’.Formatarea datelor editate în fereastra curentă, la citire, se realizează cu funcţia cscanf(), care are prototipul următor: int cscanf(char *şir_de_formatare [, lista_adrese_variabile]);. În mod similar, pentru scriere se uitlizează funcţia:

int cprintf(const char * şir_de_formatare, listă_valori_ieşire);.

V. Mutarea cursorului şi a textului Pentru mutarea unei porţiuni de ecran se foloseşte funcţia: int movetext(int x1, int y1, int x2, int y2, int x_stînga, int y_dreapta);. Porţiunea dreptunghiulară de text delimitatată de colţul din stînga sus (x1, y1) şi colţul din dreapta jos (x2, y2) se copie începînd cu poziţia de coordonate (x_stînga, y_dreapta), care constituie colţul din stînga sus al dreptunghiului care urmează să-l ocupe textul. Coordonatele sînt date în coloane – linii şi sînt suficiente pentru a delimita o porţiunea dreptunghiulară, după cum se observă în următoarea schemă grafică:

(x1, y1)

(x2, y2)Mutarea textului se face corect chiar dacă zonele sursă şi destinaţie se suprapun pe unele porţiuni, coordonatele fiind relative la ecran, nu la fereastra curentă. Se semnalează eroare dacă s-au precizat coordonate care nu se pot localiza în fereastra curentă. În situaţia unui eşec funcţia returnează 0, altfel o valoare nenulă.Schimbarea poziţiei cursorului pe suprafaţa ferestrei curente se realizează cu funcţia:

void gotoxy(int x, int y);. Se deplasează cursorul în poziţia de coordonate (x, y), unde x este coloana, iar y linia. Activarea funcţiei nu are efect dacă una din coordonate este în afara ferestrei curente.Pentru aflarea coordonatelor poziţiei curente a cursorului sănt disponibile funcţiile int wherex(void); şi int wherex(void);.

VI. Modificarea textuluiInserarea unei linii noi în poziţia marcată de cursor se descrie prin funcţia: void insline(void);. Liniile situate dedesubtul cursorului vor defila în jos cu o linie şi dacă este cazul ultima linie iese de pe ecran.

Pentru şteregerea unei linii de ecran este disponibilă funcţia: void delline(void);. Se şterge linia marcată de cursor, coloana neavînd nici o

importanţă. Liniile următoare din fereastra curentă sînt deplasate în sus cu un rînd.Pentru ştergerea unei porţiunii dintr-o linie se utilizează funcţia:

void clreol(void);. Se şterg taoate caracterele din dreapta cursorului în linia marcată de cursor. Poziţia cursorului rămîne neschimbată.

5

Page 6: Elemente de grafică în C - tex.tuiasi.ro. dr. mat. Valeria... · se memorează numărul efectiv de caractere citite, care poate să fie cel mult egal cu 4. lungimea declarată a

Ştergerea completă a informaţiilor existente în fereastra activă cu deplasarea cursorului în colţul din stînga sus (1, 1) se face cu funcţia: void clrscr();. Funcţia clrscr() nu absentează din programele prezentate în această lucrare.

VII. Gestiunea ferestrelorDeschiderea unei ferestre în care să se aranjeze date de diverse tipuri conform necesităţilor programatorului, fără să se ocupe întreg ecranul, se produce cu funcţia: void window(int x1, int y1, int x2, int y2);. Colţul din stînga sus al noii ferestre deschisă este (x1, y1), iar colţul din dreapta jos este (x2, y2). În mod normal, fereastra principală poate fi descrisă prin window(1, 1, 80, 25);. Fereastra minimă care se poate deschide este de o linie şi de o coloană. Prin tragere, ferestrele pot fi mutate oriunde pe suprafaţa ecranului sau se pot suprapune. Dacă una din coordonate este necorespunzătoare, atunci apelul funcţiei are efect nul.Din acest moment coordonatele vehiculate prin program vor fi relative la freastra curentă nou delimitată şi nu la întreg ecranul. De aceea, aflarea parametrilor caracteristici ai ferestrei curente are importanţă pentru stabilirea poziţiei curente a cursorului sau pentru adaptarea funcţiilor şi prelucrărilor ulterioare la noile condiţii de lucru.

Funcţia care permite citirea acestui set de parametri este: void getextinfo(struct text_info *dw);.

VIII. Atribute de ecranAm văzut că fiecare caracter de text, care apare pe ecran, este caracterizat printr-un octet de atribut, care se află în memoria de ecran, imediat după octetul de caracter. Deci, modul în care caracterele apar pe ecran depinde de alegerea atributului curent. Octetul de caracter are structura următoare: biţii: 7 6 5 4 3 2 1 0

b f f f i c c cunde, biţii: 0 – 2 descriu culoarea în care se afişează caracterul;

3 stabileşte intensitatea luminoasă: 1 = intensitate mare (culoare deschisă), iar 0 = intensitate redusă (culoare închisă);

4 – 6 descriu culoare fondului; 7 stabileşte clipirea caracterului (blinking): 1 = cu clipire, iar 0 =

fără clipire. În monocrom se obţine: subliniere cu bitul 0, video invers cu biţii de text 0, biţii de fond 1. Se adaugă că la utilizarea unui 0, bitul respectiv nu va fi setat. Un octet atribut 0 realizează un caracter invizibil. Astfel, porţiuni de text pot să fie vizibile sau invizibile, în funcţie de necesităţi.

Pentru stabilirea valorii octetului de atribut sînt disponibile funcţiile:1) void textcolor(int culoare); precizează culoarea textului. Valorile posibile

sînt prezentate în tabelul 14.8.1. Constante simbolice Culoare CodulBLACKBLUEGREENCYANREDMAGENTABROWN

NegruAlbastruVerdeCyanRoşuMagentaMaron

0123456

6

Page 7: Elemente de grafică în C - tex.tuiasi.ro. dr. mat. Valeria... · se memorează numărul efectiv de caractere citite, care poate să fie cel mult egal cu 4. lungimea declarată a

LIGHTGRAYDARKGRAYLIGHTBLUELIGHTGREENLIGHTCYANLIGHTREDLIGHTMAGENTAYELLOWWHITEBLINK

Gri deschisGri închisAlbastru deschisVerde deschisCyan deschisRoşu deschisMagenta deschisGalbenAlbClipitor

789101112131415128

Tabelul 14.8.1Pentru claritatea programului se recomandă utilizarea constantelor simbolice, care sînt cu efect egal, aşa cum s-a precizat în exemplul de la sfîrşitul paragrafului 6.1.1.1. Spre exemplu, cu apelul textcolor(LIGHTRED); se optează pentu textul ce urmează să se scrie să aibă caractere roşu deschis.

2) void textbackground(int culoare); precizează culoarea fondului.Numai primele 7 valori din tabelul 6.1.1.6.1 pot fi folosite pentru stabilirea culorii

fondului.3) void normalvideo(void); selectează un mod de scriere normal, adică cel

existent valabil pînă la acest punct.4) void lowvideo(void); selectează un mod de scriere mai puţin luminos, adică

bitul 3 va fi completat cu 0.5) void highvideo(void); selectează un mod de scriere cu intensitate sporită, cu

alte cuvinte înscrie în bitul 3 valoarea 1.6) void textattr(int atribut); modifică întreg octetul atribut. Prin operaţii de

mascare convenabile, cu operatorii logici binari & (conjuncţie) şi | (disjuncţie), se poate modifica atributul după necesităţi. Spre exemplu, cu aplelul textattr(BLINK | RED * 16 | WHITE); se va tipări un text roşu clipitor pe fond alb.

Trasarea unui cadru drepunghiular simplu, care poate fi completat eventual cu o tabelă de meniu, se realizează cu funcţia cadru. Ca rezultat al celor 4 apelări în programul 14.8.1, pe ecran se obţine o schemă grafică de genul:

roşu deschis

cyangalben

#include <stdio.h>#include <conio.h>#include <graphics.h>void cadru(int, int, int, int, int);

void main(){ clrscr();

cadru(1, 2, 80, 5, 12);cadru(1, 6, 80, 22, 14);cadru(64, 8, 78, 10, 11);cadru(67, 19, 78, 21, 11);getch(); }

7

Page 8: Elemente de grafică în C - tex.tuiasi.ro. dr. mat. Valeria... · se memorează numărul efectiv de caractere citite, care poate să fie cel mult egal cu 4. lungimea declarată a

void cadru(int x1, int y1, int x2, int y2, int culoare){ unsigned char css=218, co=196, cds=191, cv=179, csj=192, cdj=217; int i; textcolor(culoare); gotoxy(x1, y1); putch(css); /* Coltul stinga sus */ for( i = x1+1; i<=x2-1; ++i) putch(co); /* Linie orizontala superioara */ putch(cds); /* Coltul dreapta sus */ for( i = y1+1; i<=y2-1; ++i)

{ gotoxy(x1, i); putch(cv); /* Linie verticala stinga */ gotoxy(x2, i); putch(cv); /* Linie verticala dreapta */

} gotoxy(x1, y2); putch(csj); /* Coltul stinga jos */ for( i = x1+1; i<=x2-1; ++i) putch(co); /* Linie orizontala inferioara */ _wscroll = 0; putch(cdj); /* Coltul dreapta jos */ _wscroll = 1; getch(); }

Programul 14.8.1În ultima parte a programului s-a impus anularea temporară a scrierii pe ecran cu “scroll” pentru ca la trasarea colţului din dreapt jos să se împiedice saltul la linie nouă. În caz contrar, s-ar pierde linia superioară din cadru prin derularea conţinutului ferestrei în sus.

Dacă funcţia cadru se descrie prin intermediul structurii text_info, atunci coordonatele colţurilor stînga sus şi dreapta jos ale unui cadru vor fi precizate prin window în modulul principal. În desenarea chenarului coordonatele sînt relative la fereastra curentă, nu la întreg ecranul.

#include <stdio.h>#include <conio.h>#include <graphics.h>void cadru(int);

void main(){ clrscr();

window(1, 2, 80, 5); cadru(12);window(1, 6, 80, 22); cadru(14);window(64, 8, 78, 10); cadru(11);window(67, 19, 78, 21); cadru(11);getch(); }

void cadru(int culoare){ unsigned char css=218, co=196, cds=191, cv=179, csj=192, cdj=217; int i, dx, dy;

struct text_info dw; textcolor(culoare); gettextinfo(&dw); /*Determina dimensiunile unei ferestre */ dx = dw.winright – dw.winleft + 1; /* Latimea ferestrei */ dy = dw.winbottom – dw.wintop + 1; /* Inaltimea ferestrei */ gotoxy(1, 1); putch(css); /* Coltul stinga sus */ for( i = 2; i<=dx; ++i) putch(co); /* Linie orizontala superioara */ putch(cds); /* Coltul dreapta sus */

8

Page 9: Elemente de grafică în C - tex.tuiasi.ro. dr. mat. Valeria... · se memorează numărul efectiv de caractere citite, care poate să fie cel mult egal cu 4. lungimea declarată a

for( i = 2; i<=dy; ++i) { gotoxy(1, i); putch(cv); /* Linie verticala stinga */ gotoxy(dx, i); putch(cv); /* Linie verticala dreapta */

} gotoxy(1, dy); putch(csj); /* Coltul stinga jos */ for( i = 2; i<=dx; ++i) putch(co); /* Linie orizontala inferioara */ _wscroll=0; putch(cdj); /* Coltul dreapta jos */ _wscroll=1; getch(); }

Programul 14.8.2Logica de rezolvare a problemei şi comentariul făcut la sfîrşitul programului

anterior privitor la anularea temporară a scrierii pe ecran cu “scroll” rămîn neschimbate, doar mecanismul de codificare este altul.Observaţie. În mod analog, în modul grafic există funcţii predefinite specifice de desenare figuri geometrice, stiluri de linii şi modele de haşurare. De exemplu, pentru figurile geometrice uzuale se menţionează cîteva:

void far line(int x, int y, int x1, int y1);,void far linerel(int dx, int dy); şi

void far lineto(int x, int y);. Funcţia line() are ca efect trasarea unei linii între punctele de coordonate (x, y) şi (x1, y1), fără modificarea poziţiei curente. Pentru funcţia linerel(), punctul iniţial este poziţia curentă a cursorului, iar coordonatele punctului final se obţine incrementînd cu dx şi dy abscisa şi respectiv ordonata poziţiei curente. Punctul final devine noua poziţie curentă. Ultima funcţie desenează o linie între poziţia curentă şi punctul de coordonate (x, y), care stabileşte noua poziţie curentă.

Apelul funcţiei void far rectangle(int x, int y, int x1, int y1); permite desenarea unui dreptunghi, unde colţul din stînga sus este punctul de coordonate (x, y), iar colţul din dreapta jos este (x1, y1).

Cu funcţia void far circle(int x, int y, int r); se desenează un cerc cu centrul în (x, y) şi de rază r.

Pentru desenarea unui arc de cerc pe lîngă centrul cercului şi rază trebuie să se specifice, în grade, unghiurile de început şi de sfîrşit ale arcului:

void far arc(int x, int y, int unghi_start, int unghi_final, int r);. Dacă unghi_start este 0˚ şi unghi_final este 360˚, atunci se trasează un cerc complet.

Un arc de elipsă poate fi efectul activării funcţiei: void far ellipse(int x, int y, int unghi_start, int unghi_final, int axa_o, int axa_v);.

Consideraţii generale despre programarea orientată către obiect

Stilul de programare orientat spre obiect (POO) adaugă un grad ridicat de abstractizare programelor C++, pe lîngă modularizare şi structurare, şi permite facilităţi de adaptare şi extindere a acestora în întreţinerea versiunilor existente şi respectiv în dezvoltarea versiunilor ulterioare. Efortul de bază se îndreaptă, acum, către definirea obiectului şi a ierarhiei între obiecte.Atributele fundamentale ale POO sînt încapsularea, moştenirea şi polimorfismul.

9

Page 10: Elemente de grafică în C - tex.tuiasi.ro. dr. mat. Valeria... · se memorează numărul efectiv de caractere citite, care poate să fie cel mult egal cu 4. lungimea declarată a

1. Încapsularea. Spre deosebire de programarea procedurală, unde structurile de date se tratează separat de către algoritmi cu nivele diferite de complexitate, prin încapsularea datelor se încearcă, pe de o parte tratarea mai apropiată de realitate a structurilor de date, în sensul că se precizează, strict, numai modurile în care se poate opera asupra acestora, iar pe de alta protejarea structurilor de date împotriva unor accidente nedorite, ca de exemplu suprascrierea din greşeală. 2. Moştenirea tranzitivă. Tratarea adecvată a realităţii complexe şi diverse, în continuă transformare şi modificare, presupune traducerea în practica programării a noţiunilor de gen proxim şi diferenţă specifică. Definirea obiectului de bază cuprinde aspectele esenţiale (aspectele ce redau genul proxim) în descrierea şi manipularea obiectului. Adăugînd succesiv alte caracteristici specifice la descrierea obiectului definit anterior se obţine un nou obiect. În acest mod se poate construi o structură arborescentă de clase, de tip descendent înlănţuit. Obiectele din clasele descendente preiau automat atît datele (însuşirile, caracteristicile) cît şi metodele (capacităţile) din obiectele strămoş (definitor) pe linie ascendentă pînă la rădăcina arborelui. Cu alte cuvinte, transmiterea ereditară a caracteristicilor şi capacităţilor unui obiect într-o ierahie de obiecte este un proces tranzitiv, şi anume: dacă obiectul O2 este urmaşul obiectului O1, iar obiectul O3 este urmaşul obiectului O2, atunci O3 este urmaşul lui O1. Numărul de descendenţi este nedeterminat şi moştenirea se măreşte proporţional cu lungimea adîncimii unei ramuri. Ordinea de amplasare a textelor care definesc tipurile de clasă trebuie să cuprindă mai întîi tipurile de clasă care vor servi ca strămoş, descendenţii urmează după aceea. Definiţiile metodelor pot fi aşezate oriunde, compilatorul le culege în ordinea corectă.3. Polimorfismul. Structura metodelor care acţionează asupra obiectelor poate fi reconfigurată ulterior în cadrul ierarhiei de obiecte stabilită conform cerinţelor utilizatorului. Deci, un indentificator de recunoaştere al unei metode moştenite poate fi redefinit în cadrul ierarhiei de obiecte. Redefinirea unei metode moştenite are ca efect crearea unei noi metode cu un bloc de metodă diferit şi dacă este cazul cu o altă listă de parametri. Astfel, diferite variante ale unei metode pot acţiona automat şi în mod specific asupra obiectelor de pe diverse nivele de ierarhizare, aşa cum se întîmplă, de exemplu, în cazul metodelor virtuale.

IX. Operaţii de intrare/ieşire specifice POOPentru partea de POO, compilatorul C++ este prevăzut cu un sistem adecvat de dispozitive logice şi de operatori de citire/scriere. Pentru vizualizarea la consolă a mesajelor care permit fixarea momentelor în construirea, utilizarea şi distrugerea unui obiect dintr-o anumită clasă sînt suficienţi operatorii cin şi cout, pe care îi vom descrie în continuare. Cu alte cuvinte, dispozitivelor logice stdin şi stdout în POO le corespund operatorii cin şi respectiv cout. Specificatorii de delimitare a valorilor de intrare/ieşire, controlul formatului şi erorile de citire/scriere se tratează în acelaşi mod ca în cazul funcţiilor predefinite scanf() şi printf(). După caz, pentru execuţia unui program care conţine operatorii cin/cout este obligatorie includerea unuia din fişierele antet istream.h, ostream.h sau iostream.h.

Formatul general de citire a n valori de la tastatura calculatorului este următorul: cin >>nume_var_1>> nume_var_2>> …>>nume_var_n; unde variabilile

desemnate prin indentificatorii de recunoaştere nume_var_i, cu i = 1,2, …, n, pot avea

10

Page 11: Elemente de grafică în C - tex.tuiasi.ro. dr. mat. Valeria... · se memorează numărul efectiv de caractere citite, care poate să fie cel mult egal cu 4. lungimea declarată a

tipuri aritmetice sau pot fi şiruri de caractere. Valorile lor sînt citite în ordine, iar orice caracter invalid provoacă întreruperea operaţiei de citire.

Pentru scrierea a n valori pe ecranul calculatorului se utilizează operatorul cout cu următoarea sintaxă generală:

cout<< nume_var_1<< nume_var_2<< …<<nume_var_n;.Variabilile nume_var_i, cu i = 1,2, …, n, pot fi cu tipuri aritmetice, şiruri de caractere sau pointeri. La pointeri nu se admite tipul char.Un exemplu de utilizare a operatorilor cin şi cout se prezintă în programul de mai jos: /* Operatorii cin si cout */

#include <iostream.h> void main (void) { int i;

float j;cout << “Intrduceti i si j: ”;cin >>i>>j;cout<<”\nS-au citit valorile ”<< i<<” si ”<<j<<’\n’; }

Introduceti i si j: 15 22.45S-au citit valorile 15 si 22.45

Programul 14.9.1Alte informaţii despre POO necesită un timp îndelungat. Spre informare se recomandă consultarea bibliogafiei, prezentată în primul curs.

11