Documente Academic
Documente Profesional
Documente Cultură
Unit-ul GRAPH
1. Generalităţi
În unit-ul GRAPH sunt declarate şi definite tipuri de date, constante, variabile,
proceduri şi funcţii. Programatorul trebuie să cunoască aceste entităţi ca nume şi semnificaţie,
pentru a le putea utiliza în cunoştinţă de cauză în diferite programe care folosesc ecranul în
modul grafic, mod în care sunt afişate, în general, imagini grafice formate din puncte
independente numite pixeli. De multe ori imaginea construită de rutinele grafice trebuie să
conţină : cuvinte, numere, simboluri, formule, titluri, explicatii, etc.; într-un cuvânt texte.
Spre deosebire de unit-ul CRT, care lucrează în modul text şi care oferă un număr
restrâns de opţiuni în ceea ce priveşte caracterele afişate (se poate alege doar culoarea fondului
şi culoarea caracterelor şi, într-o măsură foarte limitată, dimensiunile caracterelor) unit-ul
GRAPH oferă mult mai multe opţiuni referitoare la modul în care şirurile de caractere sunt
afişate pe ecran. Pe lângă setul de caractere utilizate în modul text, numite şi caractere rastu, se
mai pot utiliza şi:
• caractere mărite de trei ori, care se găsesc în fişierul TRIP.CHR;
• caractere mici şi filiforme, care se găsesc în fişierul LITT.CHR;
• caractere stas ca la desen tehnic, care se găsesc în fişierul SANS.CHR;
• caractere gotice, care se găsesc în fişierul GOTH.CHR.
Caracterele din aceste fişiere se mai numesc şi caracrere vectoriale. Toate caracterele
pot fi mărite de un anumit număr de ori, iar pentru cele din fişierele *.CHR se poate stabili
independent înălţimea şi lăţimea caracterelor. Caracterele rastu nu arată bine când sunt mărite
pe când caracterele vectoriale îşi păstrează bine forma în urma măririi. Folosirea ecranului în
modul grafic, oferă posibilitatea de a stabili culoarea şi luminozitatea fiecărui pixel independent
de culoarea şi luminozitatea celorlalţi pixeli. Din punct de vedere al unit-ului GRAPH, ecranul
este privit ca un sistem de referinţă rectangular, cu originea în colţul stânga-sus, care are
coordonatele (0,0). Valoarea lui x (abscisa) creşte spre dreapta iar, valoarea lui y (ordonata)
creşte în jos. Numărul de puncte de pe o linie, respectiv coloană depinde de placheta grafică
folosită precum şi de modul grafic utilizat. Placheta grafică sau interfaţa video după cum i
se mai spune, este o componentă fizică a calculatorului, în sarcina căreia cade gestionarea
memoriei ecran şi controlul monitorului video, cu ajutorul unui soft specializat elaborat de
firmă, soft al cărui cod obiect este depus în fişierele *.BGI (Borland Graphics Interface).
Numărul de puncte dintr-o linie, respectiv coloană, poate fi aflat prin program cu ajutorul
funcţiilor GETMAXX şi GETMAXY, fapt pentru care coordonatele celor patru colţuri ale
ecanului sunt :
(0,0) (n,0)
unde : n := GETMAXX; iar m := GETMAXY;
Numărul totol de puncte de pe ecran este
( n +1) × ( m +1). Cu cât acest produs este mai
mare cu atât mai bine : spunem, de exemplu, că un
monitor de 640 × 350 pixeli are o rezoluţie mai
(0,m) (n,m) bună decât un monitor de 640 × 200 pixeli.
CGA (Color Graphics Adapter) corespunzătoare interfeţei IBM tradiţionale, fapt pentru care
indiferent de tipul plăcii grafice cu care este dotat calculatorul dumneavoastra puteţi face
referire la această interfaţă. Deoarece producătorii calculatoarelor personale din marea familie a
compatibilelor IBM PC nu au ajuns niciodată la un consens în ceea ce priveşte monitoarele
video şi mai ales interfeţele video folosite, vom prezenta în cele ce urmează un tabel cu plăcile
grafice şi modurile grafice admise de fiecare placă, acceptate de TURBO PASCAL. Tabelul va
conţine şi informaţii referitoare la: rezoluţie, numărul de culori ce se pot utiliza simultan,
numărul de pagini, numărul de biţi alocat pentru un pixel şi informaţii referioare la paleta de
culori.
urmează:
Cod culoare → 0 1 2 3
Cod paletă ↓
C0 culoare fond verde deschis roşu deschis galben
C1 culoare fond albastru deschis luminos violet alb
luminos
C2 culoare fond verde roşu maro
C3 culoare fond albastru deschis violet gri luminos
TYPE
LINESETTINGSTYPE = RECORD {atributele liniei }
LINESTIL : WORD; { stilul liniei }
PATTERN : WORD; { modelul liniei }
THICKNESS : WORD; { grosimea liniei }
END;
{Valori implicite : ( SOLIDLN,$FF,NORMWIDTH ) }
UNIT-ul GRAPH 4
{ Coduri de eroare }
CONST
GROK = 0; {Nu există eroare grafică}
GRNOINITGRAPH = - 1; {Grafica *.BGI neinstalată cu INITGRAPH }
GRNOTDETECTED = - 2; {Placa grafică nu a fost detectată}
GRFILENOTFUND = - 3; {Nu s-a găsit fişierul *.BGI corespunzător}
GRINVALIDDRIVER = - 4; {Fişierul nu conţine un driver valid}
GRNOLOADMEM = - 5; {Memorie insuficientă pentru a încărca driverul.
Procedura INITGRAPH consumă memorie dinamică,
deci măriţi dimensiunea zonei destinată alocării
dinamice.}
GRNOSCANMEM = - 6; {Memorie insuficientă pentru umplerea unei figuri prin
procedura FILLPOLY sau prin altele înrudite cu ea}
GRNOFLOODMEM = - 7; {Memorie insuficientă pentru umplerea unei figuri prin
proceduta FLOODFILL}
GRFONTNOTFOUND = - 8; {Nu s-a găsit un fişier cu caractere *.CHR}
GRNOFONTMEM = - 9; {Memorie insuficientă pentru încarcarea unui set de
caractere;soluţia : ca la -5}
GRINVALIDMODE = - 10; {Mod grafic invalid pentru driverul ales}
GRERROR = - 11; {Eroare grafică; nu precizează mai mult}
GRIOERROR = - 12; {Eroare de I/E detectată de rutinele grafice}
GRINVALIDFONT = - 13; {Fişierul cu setul de caractere, este invalid}
GRINVALIDFONTNUM = - 14; {Numărul setului de caractere este invalid}
GRINVALIDDEVICENUM = - 15; {Numărul driverului este invalid}
{ Drivere grafice }
CONST
DETECT = 0; {Driverul grafic cu cea mai mare rezoluţie corespuzător plachetei
grafice
cu care este dotat calculatorul}
CGA = 1; MCGA = 2; EGA = 3; EGA64 = 4; EGAMONO = 5;
IBM8514 = 6; HERCMONO = 7; ATT400 = 8; VGA = 9; PC3270 = 10;
CURENTDRIVER = -128;
{ Moduri grafice }
CONST
CGAC0 = 0; CGAC1 = 1; CGAC2 = 2; CGAC3 = 3; CGAHI = 4;
MCGAC0 = 0; MCGAC1 = 1; MCGAC2 = 2; MCGAC3 = 3; MCGAMED = 4;
MCGAHI = 5; EGALO = 0; EGAHI = 1; EGA64LO = 0; EGA64HI = 1;
EGAMONOHI = 3; IBM8514LO = 0; IBM8514HI = 1; HERCMONOHI = 0;
ATT400C0 = 0; ATT400C1 = 1; ATT400C2 = 2; ATT400C3 = 3;
ATT400MED = 4; ATT400HI = 5; VGALO = 0; VGAMED = 1;
VGAHI = 2; PC3270HI = 0;
UNIT-ul GRAPH 6
{ Culori normale }
CONST
BLACK = 0; RED = 4; DARKGRAY = 8; LIGHTRED = 12;
BLUE = 1; MAGENTA = 5; LIGHTBLUE = 9; LIGHTMAGENTA = 13;
GREEN = 2; BROWN = 6; LIGHTGREEN = 10; YELOOW = 14;
CYAN = 3; LIGHTGRAY = 7; LIGHTCYAN = 11; WHITE = 15;
{ Culori EGA }
CONST
EGABLACK = 0; EGARED =4; EGADARKGRAY =56;
EGALIGHTRED = 60; EGABLUE =1; EGAMAGENTA =5;
EGALIGHTBLUE =57; EGALIGHTMAGENTA=61; EGAGREEN =2;
EGABROWN =20; EGALIGHTGREEN =58; EGAYELLOW = 62;
EGACYAN = 3; EGALIGHTGRAY =7; EGALIGHTCYAN =59;
EGAWHITE = 63;
{ Stilul liniei }
CONST
SOLIDLN = 0; { Linie continuă de forma ______________}
DOTTEDLN = 1; { Linie întreruptă de forma _ _ _ _ _ _ _ _ _}
CENTERLN = 2; { Linie întreruptă de forma __ _ __ _ __ _ __}
DASHEDLN = 3; { Linie întreruptă de forma ___ ___ ___ ___ }
USERBITLN = 4; { Stil de linie definit de utilizator }
{ Grosimea liniei }
CONST
NORMWIDTH = 1; { Grosime normală } THICKWIDTH = 3; { Linie groasă }
{ Tăiere grafică }
CONST
CLIPON = TRUE; { Activează tăierea; exteriorul este invizibil}
CLIPOFF = FALSE; { Tăierea este pasivă; exteriorul este vizibil }
{ Desenare plafon }
CONST
TOPON = TRUE; { Se desenează plafonul unui paralelipiped }
TOPOFF = FALSE; { Nu se desenează plafonul şi prin urmare, deasupra nu se poate
aşeza un alt paralelipiped }
UNIT-ul GRAPH 7
{ Tipuri de caractere }
CONST
DEFAULTFONT = 0; { Caracterele implicite - caractere rastu }
TRIPLEXFONT = 1; { Caracterele din fişierul TRIP.CHR }
SMALLFONT = 2; { Caracterele din fişierul LITT.CHR }
SANSSERIFFONT = 3; { Caracterele din fişierul SANS.CHR }
GOTHICFONT = 4; { Caracterele din fişierul GOTH.CHR }
{ Direcţia de scriere }
CONST
HORIZDIR = 0; { Scriere pe orizontală de la stânga la dreapta }
VERTDIR = 1; { Scriere pe verticală de sus în jos }
{ Dimensiune caracter utilizator }
CONST
USERCHARSIZE = 0; { nu se poate folosi pentru stilul DEFAULTFONT }
{ Stilurile
Numele :detipul
haşurare a unei figuri } S e m n i f i c a ţ i a
CONST
GRAPHGETMEMPTR : POINTER; Adresa memoriei pentru grafică
EMPTYFILL = 0; { colorează cu culoarea de fond}
GRAPHFREEMEMPTR : POINTER; Adresa memoriei grafice libere.
SOLIDFILL = 1; { nuanţă uniformă temperată}
LINEFILL = 2; { linii orizontale groase}
LTSLASHFILL = 3; { model /// subţire}
SLASHFILL = 4; { model /// gros}
BKSLASHFILL = 5; { model \\\ gros }
LTBKSLASHFILL = 6; { model \\\ subţire}
HATCHFILL = 7; { model pătratele orizontale}
XHATCHFILL = 8; { model pătratele oblice}
INTERLEAVEFILL = 9; { model cu puncte dese }
WIDEDOTFILL =10; { model punctat rar}
CLOSEDOTFILL =11; {model punctat intermediar}
USERFILL =12; { model definit de utilizator}
{ Modul de desenare }
CONST
COPYPUT = 0; { desenare normală}
XORPUT = 1; { sau exclusiv - cu desenul existent }
ORPUT = 2; { sau - cu desenul existent }
ANDPUT = 3; { şi - cu desenul existent }
NOTPUT = 4; { not - cu desenul existent}
UNIT-ul GRAPH 8
Setul de proceduri şi funcţii din unit-ul GRAPH, folosite pentru iniţializarea sistemului
grafic şi tratarea erorilor grafice este prezentat în tabelul următor :
PROGRAM modgraf;
USES GRAPH,PRINTER;
TYPE vector_placi = ARRAY[1..10] OF INTEGER;
CONST dg : vector_placi = (1,2,3,4,5,6,7,8,9,10);
VAR i,j,k,min,max : INTEGER;
pc : PALETTETYPE;
BEGIN
FOR i := 1 TO 10 DO
BEGIN
WRITELN(LST,'Pentru driverul grafic cu codul ',i,' avem');
j := 0;
INITGRAPH(dg[i],j,'');
j:= graphresult;
UNIT-ul GRAPH 11
IF j <> 0 THEN
BEGIN
WRITE(LST,'Eroare grafica de tipul :');
WRITELN(LST,GRAPHERRORMSG(j));
END
ELSE
BEGIN
WRITELN(LST,'Driverul grafic incarcat este: ',GETDRIVERNAME);
GETMODERANGE(dg[i],min,max);
WRITELN(LST,'Pe acest driver se pot utiliza modurile :');
FOR j := min TO max DO
BEGIN
INITGRAPH(dg[i],j,'');
WRITE(LST,' - ',GETMODENAME(j));
WRITE(LST,' cu codul ',GETGRAPHMODE,'si');
WRITE(LST,GETMAXCOLOR + 1,' culori.');
GRAPHDEFAULTS;
WRITE(LST,'Coordonatele colturilor sint (',GETX,',');
WRITELN(LST,GETY,') - (',GETMAXX,',',GETMAXY,')');
CLOSEGRAPH;
WRITELN(LST,' ');
END;
END;
END;
END.
Problema 1. _ _
Rezolvare.
Reamintim că, dată fiind o funcţie f : D →E , graficul acesteia se defineşte ca fiind
mulţimea: G f = { ( x , y ) / x ∈D, y = f ( x )} , fapt pentru care, rezolvarea problemei anterioare
se reduce la a desena pe ecranul grafic o mulţime finită de puncte, a căror imagine de ansamblu
ar contura destul de bine graficul funcţiei f. În vederea realizării unui desen cât mai corect,
trebuie să ţinem cont de următoarele:
- pe ecran pot fi desenate doar puncte ale căror coordonate sunt numere întregi
pozitive, iar punctele care definesc graficul funcţiei f au atât coordonate pozitive cât şi
coordonate negative, care sunt în general numere reale, iar pentru a le putea desena în spaţiul
UNIT-ul GRAPH 13
fizic al ecranului, trebuie să efectuăm o translaţie a originii în centrul ecranului, care are
coordonatele (319,239);
- valorile întregi din domeniul [−2π, 2π] , pe care le poate lua argumentul x sunt
elementele mulţimii {-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6}, iar valorile întregi pe care le poate lua
functia: y=f(x), sunt elementele mulţimii {-1,0,1} şi, ceea ce este mai interesant, aceste valori
nu corespund unor argumente întregi, fapt pentru care luarea în considerare doar a argumentelor
întregi nu este o soluţie, cum, de altfel, nici considerarea a numai trei valori pentru funcţia f nu
dă nici un rezultat. Din această cauză vom impune ca x-ul să parcurgă domeniul dat cu pasul
0.01 şi vom calcula valoarea lui y=f(x), iar pentru a putea evidenţia punctul de coordonate
(x,y) pe ecranul grafic, vom considera unitatea de măsură ca fiind formată, de exemplu, din 30
de pixeli şi prin urmare vom desena punctul de coordonate ( x p , y p ) unde:
x p = 319 + [30 ⋅ x ]
y p = 239 − [30 ⋅ y ]
PROGRAM grafic_functie;
USES GRAPH;
VAR dg,mg,xp,yp,xo,yo:INTEGER;
x,y:REAL;i,j:integer;
FUNCTION f(x:REAL):REAL;
BEGIN
f:=SIN(x)+COS(x);
END;
{ PROGRAMUL PRINCIPAL }
BEGIN
dg:=9; mg:=2;
INITGRAPH(dg,mg,'');
LINE(2,2,GETMAXX-2,2); LINE(2,2,2,GETMAXY-2);
LINE(GETMAXX-2,2,GETMAXX-2,GETMAXY-2);
LINE(2,GETMAXY-2,GETMAXX-2,GETMAXY-2);
xo:=GETMAXX DIV 2; yo:=GETMAXY DIV 2;
LINE(xo,20,xo,460); LINE(20,yo,620,yo);
MOVETO(xo,20); LINEREL(-5,5);LINEREL(10,0);LINEREL(-5,-5);
MOVETO(620,yo);LINEREL(-5,-5);LINEREL(0,10);LINEREL(5,-5);
OUTTEXTXY(xo-10,10,'f(x)'); OUTTEXTXY(xo+5,yo+5,'O');
OUTTEXTXY(625,yo-5,'x');
x:=-2*PI;
WHILE x<=2*PI DO
BEGIN
y:=f(x);
xp:=xo+ROUND(40*x);
yp:=yo-ROUND(40*y);
PUTPIXEL(xp,yp,15);
x:=x+0.001;
END;
READLN;
END.
UNIT-ul GRAPH 14
Observaţie. Într-un mod cu totul analog se poate reprezenta graficul oricărei funcţii, cu
precizarea că în funcţie de necesităţi se poate alege o altă unitate de măsură, iar dacă domeniul
de definiţie sau domeniul de valori se exprimă prin numere destul de mari se poate face în
prealabil o taransformare de variabilă şi eventual o transformare de funcţie printr-o contracţie
astfel încât repreyentarea grafică să se poată face în spaţiul fizic al ecranului.
PROGRAM linii_puncte;
USES GRAPH;
VAR dg,mg,l,x1,y1 : INTEGER;
x2,y2 : LONGINT;
al : LINESETTINGSTYPE;
x : REAL;
BEGIN
dg := 9; mg := 2;
INITGRAPH(dg,mg,'');
SETWRITEMODE(0);
LINE(0,0,GETMAXX,0); LINE(0,0,0,GETMAXY);
LINE(0,GETMAXY,GETMAXX,GETMAXY);
LINE(GETMAXX,0,GETMAXX,GETMAXY);
GETLINESETTINGS(al);
WRITELN('Atributele implicite pentru linie sint;');
WRITELN(' - stilul = ',al.LINESTYLE);
WRITELN(' - modelul = ',al.PATTERN );
WRITELN(' - grosimea = ',al.THICKNESS);
SETLINESTYLE(4,$FFFF,1);
x1 := GETMAXX DIV 2;
y1 := GETMAXY DIV 2;
LINE(0,y1,GETMAXX,y1); MOVETO(GETMAXX,y1);
LINEREL(-x1,-y1); LINEREL(-x1,y1);
LINEREL(x1,y1); LINEREL(x1,-y1);
MOVEREL(-x1,-y1); LINETO(x1,GETMAXY);
x2 := x1; y2 := y1;
l := x2*y2 DIV (x2+y2); { l este jumatate din latura patratului }
SETLINESTYLE(0,0,3); SETWRITEMODE(1);
LINE(x1-l,y1-l,x1-l,y1+l); MOVETO(x1-l,y1+l);
LINETO(x1+l,y1+l); LINEREL(0,-2*l);
LINEREL(-2*l,0);
x := 0;
WHILE x <= 2*PI DO
BEGIN
x2 := ROUND(l*COS(x));
y2 := ROUND(l*SIN(x));
PUTPIXEL(x1+x2,y1-y2,MAXCOLORS);
x := x + 0.001;
END;
{end while}
END.
UNIT-ul GRAPH 16
PROGRAM poligoane_hasurari;
USES GRAPH;
TYPE puncte = ARRAY[1..7] OF POINTTYPE;
VAR dg,mg,i,j,dy : INTEGER;
hexagon : puncte;
p : POINTTYPE;
CONST stil : FILLPATTERNTYPE = ($88,$88,$88,$88,$88,$88,$88,$88);
PROCEDURE coordonate(VAR hexagon:puncte);
BEGIN
p.X := 49*j - 24; p.Y := 71*i -15; p.X := p.X + 22;
MOVE(p,hexagon[1],4); MOVE(p,hexagon[7],4);
p.X := p.X - 44; MOVE(p,hexagon[4],4);
dy := ROUND(22*SIN(PI/3)); p.Y := p.Y + dy;
p.X := p.X + 33; MOVE(p,hexagon[2],4);
p.X := p.X - 22; MOVE(p,hexagon[3],4);
p.Y := p.Y - 2 * dy; MOVE(p,hexagon[5],4);
p.X := p.X + 22; MOVE(p,hexagon[6],4);
END;
PROCEDURE desene;
BEGIN
FOR i := 1 TO 6 DO
CASE i OF
1 : RECTANGLE(49*j-37,71*i-39,49*j-12,71*i+8);
2 : BAR(49*j-37,71*i-39,49*j-12,71*i+8);
3 : BAR3D(49*j-37,71*i-32,49*j-15,71*i+13,10,TRUE);
4 : BEGIN
coordonate(hexagon); DRAWPOLY(7,hexagon);
END;
5 : BEGIN
coordonate(hexagon); FILLPOLY(7,hexagon);
END;
6 : BEGIN
coordonate(hexagon); DRAWPOLY(7,hexagon);
FLOODFILL(49*j-24,71*i-15,15);
END;
END;
END;
BEGIN
dg := 9; mg := 2; INITGRAPH(dg,mg,'');
SETLINESTYLE(0,0,1); LINE(0,0,637,0);
FOR i := 1 TO 7 DO
LINE(0,20+71*(i-1),637,20+71*(i-1));
FOR j := 1 TO 14 DO
BEGIN
SETTEXTSTYLE(2,0,3);
IF j <= 10 THEN
OUTTEXTXY(49*(j-1)+5,5,'STIL - '+ CHR(47+j))
ELSE
OUTTEXTXY(49*(j-1)+5,5,'STIL - '+ CHR(49) + CHR(47+j MOD 10));
LINE(49*(j-1),0,49*(j-1),446);
END;
FOR j := 1 TO 12 DO
BEGIN
SETFILLSTYLE(j-1,15); desene;
END;
j := 13; SETFILLPATTERN(stil,15); desene;
SETTEXTSTYLE(1,0,2);
OUTTEXTXY(150,450,'Poligoane si stiluri de hasurare.');
END.
UNIT-ul GRAPH 20
Sistemele de calcul care admit plăcile grafice: EGA, EGA64, HERCMONO şi VGA
oferă posibilitatea de a utiliza mai multe pagini de memorie ecran, şi implicit facilităţi mult
mai elegante în realizarea aplicaţiilor complexe, gen animaţie. Tot odată există posibilitatea
de a construi unele imagini în anumite zone dreptunghiulare de pe ecran şi de a le salva în
memorie la anumite adrese sau de a suprapune peste o zonă de ecran imaginea salvată într-o
anumită zonă de memorie, efectuând între cele două imagini una din operaţiile precizate prin
constantele predefinite ce definesc modul de desenare. Precizăm că se pot salva imagini a
căror dimensiune este mai mică de 64 Ko. Numărul de biţi alocat pentru un pixel este egal cu
logaritmul în baza 2 din numărul de culori utilizate într-un mod grafic, fapt pentru care
dimensiunea unei zone de memorie în care se salvează o imagine este egală cu
ROUND(n*m*b/8), unde n şi m sunt dimensiunile zonei, exprimate în număr de pixeli, iar b
reprezintă numărul de biţi/pixel. Procedurile disponibile care pot fi utilizate în scopurile
precizate mai sus, sunt următoarele:
Numele / sintaxa Tipul Efectul
Deschide o nouă pagină pentru ecranul grafic.
SETACTIVEPAGE(np); Proc. Parametrul np reprezintă numărul paginii în care se
np:WORD; va construi imaginea grafică; numerotarea paginilor
începe de la zero.
SETVISUALPAGE(np); Proc. Afişează pe ecran pagina np, în care a a fost
np:WORD; construită o imagine.
În unit-ul GRAPH avem la dispoziţie proceduri pentru a desena cercuri, elipse, arce
de cerc,arce de elipsă, sectoare de cerc şi sectoare de elipsă. Deoarece în marea majoritate a
cazurilor, forma figurilor desenate pe ecran trebuie controlată foarte precis, precizăm că pixelii
nu sunt pătraţi decât în cazuri particulare (cum ar fi modul grafic VGAHI), iar în general sunt
dreptunghiulari, unităţile de măsură pe cele două axe fiind diferite, dimensiunea pe OX este
mai mică decât dimensiunea pe OY.
În cele ce urmează vor fi trecute în revistă procedurile cu care pot fi desenate figurile
precizate mai sus precum şi două proceduri foarte utile pentru a controla fenomenele de
deformare, care devin neplăcute în unele situaţii.
Numele / sintaxa Tipul Efectul
Desenează un cerc cu centrul în punctul de coordonate
CIRCLE(x,y,r); x,y şi de rază r. Raza r este exprimată în număr de
x,y:INTEGER; proc. pixeli iar din punct de vedere fizic mărimea razei este
r:WORD; egală cu produsul r × dx , unde dx dimensiunea unui
pixel pe direcţia OX.
Desenează un arc din cercul cu centrul în punctul de
ARC(x,y,u1,u2,r); coordonate x,y şi rază r, arc cuprins între unghiurile de
x,y:INTEGER; proc. început şi sfârşit notate cu u1 respectiv u2. Valorile
u1,u2,r:WORD; unghiurilor trebuie exprimate în grade în sens direct
trigonometric. Dacă u1 este 0, iar u2 este 360 se va
desena un cerc.
UNIT-ul GRAPH 24
EXEMPLUL nr.1. Următorul program împarte ecranul grafic de rezoluţie 640 x 480 în şase
pătrate de 200 x 200 pixeli, iar apoi în fiecare pătrat desenează: un cerc, o elipsa, 12 arcuri de
cerc, 12 arcuri de elipsa,12 sectoare de cerc şi 12 sectoare de elipsă , fiecare sector fiind
haşurat cu un alt model, modelele fiind cele predefinite. Extremităţile ultimului arc de elipsă se
unesc cu centrul acesteia.
UNIT-ul GRAPH 25
PROGRAM conice_arcuri_sectoare;
USES GRAPH;
VAR dg,mg,i,j,k : INTEGER;
ar : ARCCOORDSTYPE;
PROCEDURE conice;
BEGIN
FOR j:= 1 TO 2 DO
IF j = 1 THEN CIRCLE(201*i-81,201*j-61,75)
ELSE FILLELLIPSE(201*i-81,201*j-61,75,50);
END;
PROCEDURE arcuri;
BEGIN
FOR j := 1 TO 2 DO
BEGIN
k := 0;
WHILE k <= 330 DO
BEGIN
IF j = 1 THEN ARC(201*i-81,201*j-61,k,k+20,75)
ELSE ELLIPSE(201*i-81,201*j-61,k,k+20,75,50);
k := k+30;
END;
END;
GETARCCOORDS(ar); LINE(ar.X,ar.Y,ar.XSTART,ar.YSTART);
LINE(ar.X,ar.Y,ar.XEND,ar.YEND);
END;
PROCEDURE sectoare;
BEGIN
FOR j := 1 TO 2 DO
BEGIN
k := 0;
WHILE k <= 330 DO
BEGIN
SETFILLSTYLE(k DIV 30,15);
IF j = 1 THEN PIESLICE(201*i-81,201*j-61,k,k+20,75)
ELSE SECTOR(201*i-81,201*j-61,k,k+20,75,50);
k := k+30;
END;
END;
END;
BEGIN
dg := 9; mg := 2; INITGRAPH(dg,mg,'');
FOR i := 1 TO 4 DO LINE(201*i - 182, 20,201*i - 182,441);
LINE(20,20,622,20);
FOR j := 1 TO 3 DO LINE(19,201*j-162,622,201*j-162);
FOR i := 1 TO 3 DO
CASE i OF
1 : conice;
2 : arcuri;
3 : sectoare;
END;
SETTEXTSTYLE(2,0,4); OUTTEXTXY(100,25,'CONICE');
OUTTEXTXY(300,25,'ARCURI'); OUTTEXTXY(500,25,'SECTOARE');
END.
UNIT-ul GRAPH 26
PROGRAM cerc_aspect;
USES GRAPH;
VAR x1,y1,x2,y2,dg,mg : INTEGER;
px,py,rx,ry : WORD;
x : REAL;
i,j:integer;
PROCEDURE cerc2;
BEGIN
x := 0;
WHILE x <= 2*PI DO
BEGIN
x2 := ROUND(y1*COS(x));
y2 := ROUND(y1*SIN(X));
PUTPIXEL(x1+x2,y1-y2,15);
x := x+0.01;
END;
{end while}
END;
PROCEDURE cerc3;
BEGIN
PROCEDURE cerc3;
BEGIN
GETASPECTRATIO(px,py);
ry := y1;
rx := ROUND(py/px*ry);
x := 0;
WHILE x <= 2*PI DO
BEGIN
x2 := ROUND(rx*COS(x));
y2 := ROUND(ry*SIN(x));
PUTPIXEL(x1+x2,y1-y2,15);
x := x+0.02;
END;
{end while}
END;
BEGIN
dg:=9; mg:=0;
INITGRAPH(dg,mg,'');
RECTANGLE(0,0,GETMAXX,GETMAXY);
x1 := GETMAXX DIV 2; y1 := GETMAXY DIV 2;
PUTPIXEL(x1,y1,15);
CIRCLE(x1,y1,y1);
cerc2;
cerc3;
CIRCLE(x1,y1,ROUND(y1*py/px)-10);
READLN;
END.
UNIT-ul GRAPH 27
Concluzii
1. Ar fi fost de aşteptat ca primul cerc desenat cu CIRCLE să fie tangent
dreptunghiului în punctele (x1,0) respectiv (x1,GETMAXY) şi de fapt nu am obţinut aşa ceva.
Care este explicaţia? Raza precizată în CIRCLE este, aşa după cum am precizat anterior, raza
pe direcţia OX şi deoarece dimensiunea unui pixel pe OX este mai mică decât dimensiunea pe
OY, raza pe OY a fost ajustată astfel încât să coincidă cu raza de pe OX ca mărime fizică şi nu
ca număr de pixeli.
2.Al doilea cerc, desenat prin puncte cu procedura cerc2 are aspectul unei elipse. În
acest caz raza pe OX coincide cu raza pe OY ca număr de pixeli şi sunt egale cu y1. Acest cerc
este într-adevăr tangent dreptunghiului în punctele indicate.
3.Procedura cerc3, desenează un cerc prin puncte, cerc care are raza pe OY egală cu
y1, iar raza pe OX se determină înmulţind raza de pe direcţia OY cu raportul dimensional py/px
obţinut din procedura SETASPECTRATIO. Cele două raze sunt egale ca mărimi fizice şi cercul
este tangent dreptunghiului.Cercul este desenat punctat rar.
4.Ultimul cerc a fost desenat cu procedura CIRCLE, şi pentru ca el să fie tangent
dreptunghiului a trbuit să înmulţim raza y1 cu raportul dimensional py/px. Acest cerc se
supapune peste cercul punctat rar şi desenat cu procedura cerc3.
Fiecare mod grafic are propriile lui reguli de identificare a culorilor, fapt pentru care
este foarte greu de găsit un numitor comun. Singura noţiune care se poate aplica tuturor
modurilor grafice este eceea de paletă. Insistăm asupra faptului ca numai ideea generală este
comună, realizarea concretă diferind de la un mod la altul. După cum am mai precizat anterior
fiecare mod grafic se caracterizează printr-un număr specific de biţi alocaţi pentru fiecare
pixel. Din numărul de biţi alocaţi unui pixel rezultă numărul de culori ce pot fi afişate simultan
pe ecran; de exemplu, în modul grafic VGAHI fiecare pixel are 4 biţi, deci pe ecran putem
avea cel mult 16 culori simultan (24 = 16). Ce este paleta ?. Valoarea binară asociata unui
UNIT-ul GRAPH 28
pixel nu determină direct culoarea acestuia, ci este folosită ca indice într-o tabelă de culori
numită paletă. În anumite moduri grafice, programatorul poate modifica total sau parţial
conţinutul unei palete. De exemplu, pentru paleta asociata modului grafic CGAC0 avem:
Valoarea binară Numărul intrării Culoarea
asociată unui pixel în paletă
00 0 fond (poate fi aleasă de progamator din 16 culori)
01 1 Verde deschis (nemodificabilă)
10 2 roşu deschis (nemodificabilă)
11 3 galben (nemodificabilă)
Luând ca şi criteriu de clasificare posibilităţile de utilizare a culorilor, modurile grafice
pot fi împărţite în:
- moduri grafice monocrome: pixelii pot fi stinşi (culoarea neagră) sau aprinşi. În cazul
modurilor CGAHI, MCGAMED, MCGAHI, ATT400MED şi ATT400HI se poate alege culoarea
pixelilor aprinşi, iar pentru modurile HERCMONOHI şi PC3270HI nu este posibil acest lucru;
- moduri grafice cu nuanţe fixe: se caracterizează prin aceea că utilizatorul nu poate
modifica nuanţele afişate pe ecran; modurile grafice cu nuanţe fixe sunt: CGAC0, CGAC1,
CGAC2, CGAC3, MCGAC0, MCGAC1, MCGAC2, MCGAC3, EGALO, EGAHI, EGA64LO,
EGA64HI, ATT400C0, ATT400C1, ATT400C2, ATT400C3. Precizăm faptul că pentru
modurile grafice care admit paletele de culori C0, C1, C2 şi C3 se poate modifica totuşi
culoarea fondului;
UNIT-ul GRAPH 29
- moduri grafice cu nuanţe alese prin program: fiecare dintre nuanţele paletei poate fi
aleasă prin program ca o combinaţie între culorile fundamentale roşu, verde şi albastru. Aceste
moduri, oferă cea mai mare libertate programatorului, numărul de culori afişabile fiind foarte
mare (262144 pentru driver-ul IBM8514) dar dintre acestea numai o mică parte pot fi afişate
simultan pe ecran, şi anume atâtea câte intrări are paleta. Modurile grafice la care nuanţele pot
fi alese prin program sunt: VGALO, VGAMED, VGAHI, IBM8515LO, IBM8514HI.
Componenţa tricromatică a celor 16 culori EGA este prezentată în tabelul:
PROGRAM culori;
USES GRAPH,PRINTER;
TYPE vector_placi = ARRAY[1..10] OF INTEGER;
CONST dg : vector_placi = (1,2,3,4,5,6,7,8,9,10);
VAR i,j,k,min,max : INTEGER;
p : PALETTETYPE;
BEGIN
FOR i := 1 TO 10 DO
BEGIN
WRITELN(LST,'Pentru placa grafica cu codul ',i,' avem :');
j := 0; INITGRAPH(dg[i],j,''); j := GRAPHRESULT;
IF j <> 0 THEN
WRITELN(LST,' -eroare grafica de tipul :', GRAPHERRORMSG(j));
ELSE
BEGIN
WRITE(LST,'- driverul grafic incarcat este : ', GETDRIVERNAME);
GETMODERANGE(dg[i],min,max);
WRITELN(LST,'- se pot utiliza urmatoarele moduri :');
FOR j := min TO max DO
BEGIN
INITGRAPH(dg[i],j,'');
WRITE(LST,' - ',GETMODENAME(j));
WRITE(LST,' cu codul ',GETGRAPHMODE,' si ');
WRITELN(LST,GETMAXCOLOR + 1,' culori. ');
GETDEFAULTPALETTE(p);
WRITELN(LST,' - pleta implicita este :');
WRITE(LST, ' ( SIZE : ',p.SIZE,' ; COLORS : (');
FOR k:= 0 TO p.SIZE-2 DO WRITE(LST,p.COLORS[k],',');
WRITELN(LST,p.COLORS[p.SIZE-1],'))');WRITELN;
END;
END;
END;