14 elemente de grafica in pascal

23
133 14. Elemente de grafic• elementar• în Pascal (Utilizarea unit-ului Graph ) 14.1. Utilizarea ecranului în mod grafic. Exist• dou• moduri de lucru cu ecranul: modul grafic •i modul text. În ambele moduri, ecranul este privit ca o re•ea dreptunghiular• ce con•ine elemente de acela•i fel. În modul text acestea sunt caracterele utilizate în scrierea obisnuit•, iar în modul grafic elementele sunt puncte, cu ajutorul c•rora se construiesc diferite figuri. Limbajul Pascal ne ofer• posibilitatea de a utiliza ecranul •i în modul grafic prin apelul rutinelor grafice aflate în unitul Graph. În acest unit sunt declarate constante, tipuri de date, variabile, func•ii •i proceduri care pot fi utilizate în Turbo Pascal. Reamintim c• programul care apeleaz• rutinele grafice din unitul Graph va declara aceasta prin propozi•ia Uses Graph. Pentru a utiliza ecranul în mod grafic, va trebui mai întâi s• select•m modul grafic, adic• s• trecem ecranul din modul text în modul grafic prin iniializarea sesiunii grafice. În sesiunea grafic• se pot trasa diverse primitive grafice (puncte, segmente, dreptunghiuri, cercuri, elipse, etc.) în diverse culori, iar pe un desen realizat se pot aplica diverse mesaje utilizând diferite fonturi aflate la dispozitia programatorului. La terminarea sesiunii grafice sistemul va reveni în modul text. Calculatoarele IBM_PC pot fi echipate cu diverse adaptoare grafice, pentru care Turbo_Pascal are construit câte un driver grafic. De exemplu pentru adaptorul grafic IBM EGA sau VGA driverul grafic este EGAVGA.BGI.

Upload: sucea-marius-cristinel

Post on 26-Jul-2015

337 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: 14 Elemente de Grafica in Pascal

133

14. Elemente de grafic• elementar• în Pascal

(Utilizarea unit-ului Graph )

14.1. Utilizarea ecranului în mod grafic.

Exist• dou• moduri de lucru cu ecranul: modul grafic •i modul text. În

ambele moduri, ecranul este privit ca o re•ea dreptunghiular• ce con•ine elemente

de acela•i fel. În modul text acestea sunt caracterele utilizate în scrierea obisnuit•,

iar în modul grafic elementele sunt puncte, cu ajutorul c•rora se construiesc

diferite figuri.

Limbajul Pascal ne ofer• posibilitatea de a utiliza ecranul •i în modul

grafic prin apelul rutinelor grafice aflate în unitul Graph. În acest unit sunt

declarate constante, tipuri de date, variabile, func•ii •i proceduri care pot fi

utilizate în Turbo Pascal. Reamintim c• programul care apeleaz• rutinele grafice

din unitul Graph va declara aceasta prin propozi•ia Uses Graph.

Pentru a utiliza ecranul în mod grafic, va trebui mai întâi s• select•m

modul grafic, adic• s• trecem ecranul din modul text în modul grafic prin

ini•ializarea sesiunii grafice.

În sesiunea grafic• se pot trasa diverse primitive grafice (puncte,

segmente, dreptunghiuri, cercuri, elipse, etc.) în diverse culori, iar pe un desen

realizat se pot aplica diverse mesaje utilizând diferite fonturi aflate la dispozitia

programatorului.

La terminarea sesiunii grafice sistemul va reveni în modul text.

Calculatoarele IBM_PC pot fi echipate cu diverse adaptoare grafice,

pentru care Turbo_Pascal are construit câte un driver grafic. De exemplu pentru

adaptorul grafic IBM EGA sau VGA driverul grafic este EGAVGA.BGI.

Page 2: 14 Elemente de Grafica in Pascal

134

În modul grafic, ecranul poate fi

considerat ca fiind format dintr-o matrice

de puncte (pixeli).

Un punct de pe ecran poate fi aprins

(colorat) într-o anumit• culoare iar pozi•ia

s• este definit• prin coordonatele sale u •i v

reprezentând coloana, respectiv linia,

unde:

0≤ u < Dmx, Dmx = dimensiunea maxim• pe coloan•, iar

0≤ v < Dmy, Dmy = dimensiunea maxima pe linie.

Limitele Dmx •i Dmy depind de placa grafic• iar valorile acestora sunt

returnate de c•tre func•iile GetMaxX respectiv GetMaxY. De exemplu pentru

pl•ci de tipul EGAHi sau VGAMed, Dmx=640 iar Dmy=350.

Dac• dorim s• tras•m pe ecran primitive grafice referite prin coordonate

aflate într-un domeniu real, va trebui s• aplicam o transformare a acestor

coordonate, pentru c• instruc•iunile grafice refer• puncte de coordonate întregi

din domeniul [0 , Dmx] × [0 , Dmy].

Exist• posibilitatea de a realiza un

desen doar pe o por•iune a ecranului, pe un

subdomeniu [u1,u2] × [v1,v2] al domeniului

maxim [0,Dmx]×[0,Dmy].

Acest subdomeniu îl vom numi

fereastra fizic• (ViewPort) •i va fi precizat

prin coordonatele ecran a dou• puncte

diagonal opuse P1(u1,v1) •i P2(u2,v2).

0 u Dmx

0

v

Dmy

o P(u,v)

WiewPort

P1(u1,v1) v1

v2

o

o P2(u2,v2)

u1 u2

Page 3: 14 Elemente de Grafica in Pascal

135

14.2. Instruc•iuni grafice.

Instruc•iunile grafice utilizeaz• proceduri, func•ii, tipuri de date, constante

•i variabile din unitul Graph. În acest paragraf vom descrie câteva din

posibilit••ile de lucru în mod grafic.

Deschiderea unei sesiuni grafice (trecerea în modul de lucru grafic) se

execut• prin apelul procedurii InitGraph (Gd,Gm,Pd) unde:

- Gd este parametrul "GraphDriver" •i poate lua valori întregi, de exemplu

0=Detect (selectare automat• în func•ie de tipul pl•cii grafice de nivel cel

mai înalt), 3=EGA, 9=VGA, etc.

- Gm este parametrul "GraphMode" •i poate lua valori întregi de exemplu

1=EGAHi, 2=VGAHi, etc.

- Gp este parametrul "PathToDriver" de tip string care precizeaz• calea

pentru driverele grafice (subdirectorul în care se afl• fi•ierul

EGAVGA.BGI, de exemplu : ‘C:\Tp\Bgi’).

Trecerea cu succes în modul grafic se poate verifica cu ajutorul func•iei

GraphResult care returneaz• codul erorii opera•iei. Dac• trecerea a fost realizat•

corect atunci codul de retur va fi nul (0=GrOk).

Instruc•iunile grafice (func•ii •i proceduri ale unit-ului Graph) vor

func•iona corect doar pe timpul sesiunii grafice (în mod grafic între InitGraph •i

CloseGraph).

Programul urm•tor îsi propune s• deseneze ni•te cercuri în cazul în care

reu•este s• treac• în modul grafic, iar în caz contrar s• tip•reasca un mesaj de

nereu•it• a ini•ializ•rii grafice.

Program Modul_Grafic; {Programul 1. Modul Grafic}

Uses Graph; {Refera Unit_ul Graph.Tpu}

Var Gd,Gm : integer; {GraphDriver •i GraphMode}

Pd : string; {Path To Driver}

Page 4: 14 Elemente de Grafica in Pascal

136

Begin

Gd:=Detect; {Selectare automata}

Pd:=’F:\Soft\Tp\Bgi’; {Calea fisierlui EGAVGA.Bgi}

InitGraph (Gd,Gm,Pd); {Selectarea modului grafic}

If GraphResult<>0 Then {Daca nu am trecut}

Begin {in modul grafic}

Write(’Eroare InitGraph.’); {tipareste mesaj}

Readln; Halt(1) {de eroare •i stop}

End; {If}

Circle (300,200,100); Circle (250,150, 10); {Deseneaza Cercuri(Xo,Yo,Raza)}

Circle (350,150, 10); Circle (290,200, 3);

Circle (310,200, 3); Circle (300,250, 20);

Readln; {Asteapta Enter inainte de a se sterge ecranul}

CloseGraph {Termina sesiunea grafica}

End.

Procedura Circle (Xo,Yo,R) apelat• în exemplul anterior traseaz• un cerc

cu centrul în punctul de coordonate (Xo,Yo) de raz• R.

În mod normal, desenarea se execut• pe tot ecranul. Este îns• posibil s•

alegem doar o parte a ecranului pe care s• desen•m, numit• fereastr• ecran

(ViewPort). Definirea ferestrei ecran pe care vom desena se realizeaz• prin

procedura

SetViewPort(u1,v1, u2,v2, decupat)

Prin u1,v1, u2,v2 vom preciza fereastra fizic• în care vom efectua opera•ii

grafice. Ace•ti parametri sunt de tip întreg •i îndeplinesc urm•toarele restric•ii:

o

o P2(u2,v2)

0 ≤ u1 < u2 < GetMaxX

0 ≤ v1 < v2 < GetMaxY

WiewPort

0

v1

v2

GetMaxY

P1(u1,v1)

0 u1 u2 GetMaxX

Page 5: 14 Elemente de Grafica in Pascal

137

Parametrul "decupat" este de tip boolean. Dac• are valoarea True

(ClipOn) atunci la desenarea unei primitive grafice se va decupa portiunea din

fereastra definit•. Dac• acest parametru are valoarea False (ClipOff) nu se execut•

decuparea, ceea ce înseamn• c• va fi vizibil• toat• primitiva grafica, chiar dac•

aceasta dep••este domeniul ferestrei. În Unitul Graph sunt definite constantele

ClipOn •i ClipOff având valorile True respectiv False.

Dup• declararea unei ferestre fizice prin procedura SetViewPort, un punct

se va referi prin coordonatele relative la aceast• fereastr•.

În exemplul urm•tor se vor trasa ni•te cercuri înaintea definirii unei

ferestre fizice •i dup• definirea unor astfel de ferestre, cu •i f•r• decupare.

Program Ferestre_Ecran; {Programul 2. Cercuri}

Uses Graph; {Refera Unit_ul Graph.Tpu}

Type Da_Nu=(Da,Nu);

Var Gd,Gm: integer; Pd: string;{GraphDriver •i GraphMode; Path To Driver }

Procedure Cercuri(u1,v1,u2,v2: integer;Dec:Da_Nu); {Deseneaza cercuri in }

Begin { fereastra ecran cu/fara decupare}

If Dec=Da

Then SetViewPort(u1,v1,u2,v2,ClipOn )

Else SetViewPort(u1,v1,u2,v2,ClipOff);

Circle (100,100,100); Circle ( 50, 50, 10); Circle (150, 50, 10);

Circle ( 90,100, 3); Circle (110,100, 3); Circle (100,150, 20);

End;

o

v1

v M(u’,v’)

u1 u

u’ = u-u1

v’ = v-v1

Page 6: 14 Elemente de Grafica in Pascal

138

Begin

Gd:=Detect; {Selectare automata}

Pd:=’c:\Tp\Bgi’; {Calea fis. EGAVGA.Bgi}

InitGraph (Gd,Gm,Pd); {Trec in mod grafic}

If GraphResult<>0 Then Begin {Sunt in mod grafica?}

Write (’Eroare InitGraph.’);

Readln; Halt (1)

End; {Deseneaza in diferite ferestre ecran}

Cercuri( 0, 0,200,200,Da); {stanga-sus, integral}

Cercuri(400, 0,600,200,Da); {dreapta-sus, integral}

Cercuri(250, 0,350,200,Da); {centru-sus, decupat stanga}

Cercuri( 0,250,200,350,Da); {stanga-jos, decupat sus}

Cercuri(250,250,350,350,Da); {centru-jos, decupat stanga-sus}

Cercuri(400,250,400,250,Nu); {dreapta-jos, nedecupat}

Readln; CloseGraph {Termina sesiunea grafica}

End.

Stergerea ecranului se poate realiza în întregime utilizând procedura

ClearDevice sau numai pe domeniul unei ferestre fizice declarate anterior,

utilizând procedura ClearViewPort.

Selectarea culorilor se realizeaz• prin apelul urm•toarelor proceduri:

SetColor(Culoare_cerneala), care alege culoarea de desenare, iar procedura

SetBkColor(Culoare_fond) alege culoarea fondului ecranului. Parametrii acestor

proceduri sunt de tip întreg, pot lua valori din domeniul 0..15 •i reprezint• codul

culorii dorite. În unitul Graph sunt declarate urm•toarele constante ce pot fi

utilizate de c•tre programator:

Black = 0; DarkGray = 8;

Blue = 1; LightBlue = 9;

Green = 2; LightGreen = 10;

Cyan = 3; LightCyan = 11;

Red = 4; LightRed = 12;

Magenta = 5; LightMagenta = 13;

Brown = 6; Yellow = 14;

LightGray = 7; White = 15;

Page 7: 14 Elemente de Grafica in Pascal

139

Func•iile GetColor •i GetBkColor returneaz• culoarea curent• a cernelii

respectiv a ecranului.

Coordonatele punctului curent (cursorului grafic) pot fi ob•inute prin

apelurile func•iilor GetX •i GetY care returneaz• aceste valori (coordonatele

ultimului punct referit).

Punctul curent se poate muta (î•i poate schimba coordonatele f•r• trasare)

prin apelul procedurilor MoveTo(un,vn) sau MoveRel(Du,Dv). Procedura MoveTo

mut• vârful creionului grafic în punctul de coordonate (un,vn), acesta devenind

noul punct curent. Procedura MoveRel translateaz• punctul curent cu valorile

(Du,Dv), ceea ce permite precizarea coordonatelor noului punct curent în

coordonate relative fa•• de ultimul punct referit (vechea pozi•ie).

Unitul Graph con•ine rutine pentru trasarea unor primitive grafice, care

vor fi descrise în continuare.

Procedura PutPixel(u,v,c) deseneaz• în culoarea c punctul de coordonate

u,v.

Func•ia GetPixel(u,v) returneaz• codul culorii unui punct de coordonate

u,v. Pentru aceast• func•ie am ales un exemplu în care ne propunem s• umplem o

zon• din ecran cu o anumit• culoare. Aceasta zon• este format• din punctele la

care se poate ajunge mergând doar pe linie sau coloan• prin puncte de aceea•i

culoare cu un punct interior precizat.

Program Culoare_Pixel; Uses Graph; {Programul 3. Colorare }

Var Gd,Gm: integer; Pd: string;

Procedure Colorare(u,v,cn: integer); {Colorare din punctul (u,v) }

Var Cv: integer; { cu culoarea cn }

Procedure Umplere(u,v:integer);

Begin If GetPixel(u,v)=Cv Then Begin PutPixel(u,v,Cn);

Umplere (u+1,v); Umplere (u-1,v); Umplere (u,v+1); Umplere (u,v-1);

End End;

Begin

Cv:=GetPixel(u,v); Umplere(u,v);

End;

Page 8: 14 Elemente de Grafica in Pascal

140

Begin

Gd:=Detect; Pd:=’F:\Soft\Tp\Bgi’;

InitGraph (Gd,Gm,Pd);

If GraphResult<>0 Then

Begin

Write (’Eroare InitGraph’); Readln; Halt(1)

End;

SetColor(Blue); Circle(300,200,35);

SetColor(LightBlue); Circle(290,190, 7); Circle(310,190, 7);

SetColor(Brown); Circle(297,200, 2); Circle(303,200, 2);

SetColor(LightRed); Circle (300,217,10);

Colorare (300,200,Yellow); {Colorare din}

Readln; {punctul (300,200)}

CloseGraph {cu culoarea galben}

End.

În exemplul prezentat, frontiera zonei ce va fi colorat• este format• din

puncte de culoare diferit• de cea a punctului interior dat.

Procedura Line(ui,vi,uf,vf) traseaz• în culoarea curent• segmentul ce are ca

extremit••i punctele (ui,vi) •i (uf,vf). De exemplu Line(0,0,GetMaxX,GetMaxY),

are ca efect desenarea diagonalei principale a ecranului.

Un segment se mai poate trasa utilizând procedura LineTo (uf,vf) care

deseneaz• segmentul determinat de ultimul punct referit (punctul curent) •i

punctul de coordonate (uf,vf) precizat prin parametrii procedurii LineTo. Apelul

Line(ui,vi,uf,vf) este echivalent cu MoveTo(ui,vi) urmat de LineTo(uf,vf). În

paragraful urm•tor (14.3) este dat un exemplu de reprezentare grafic• a unor

func•ii în care sunt utilizate procedurile Line •i LineTo (programul 14.7).

Procedura LineRel (Du,Dv) traseaz• un segment de la punctul curent

P(u,v) pâna la punctul P’(u+Du,v+Dv). Programul urm•tor permite realizarea

unui desen prin segmente orizontale •i verticale utilizând tastele O, P, Q •i A

pentru trasarea spre stânga (Du=−5), dreapta (Du=+5), sus (Dv=−5) respectiv jos

(Dv=+5).

Page 9: 14 Elemente de Grafica in Pascal

141

Program Desen; Uses Graph, Crt; {Programul 14.4. Linie franta}

Const l=5;

Var Gd,Gm: integer; Pd : string; Sens : Char;

Begin

Gd:=Detect; Pd:=’F:\Soft\Tp\Bgi’; InitGraph (Gd,Gm,Pd);

If GraphResult<>0 Then Begin Write (’Eroare InitGraph.’); Halt (1) End;

MoveTo(GetMaxX Div 2, GetMaxY Div 2); {Centrul ecranului }

Repeat

Repeat Until KeyPressed; Sens:=UpCase(ReadKey);

Case Sens Of

’O’: LineRel (-l, 0);

’P’: LineRel ( l, 0);

’Q’: LineRel ( 0,-l);

’A’: LineRel ( 0, l)

End {Case}

Until not (Sens in [’O’,’P’,’Q’,’A’]); Readln; CloseGraph

End.

Procedura Rectangle (ui,vi,uf,vf) deseneaz• dreptunghiul determinat de

vârfurile diagonal opuse (ui,vi) •i (uf,vf). De exemplu Rectangle (0,0,100,100)

deseneaz• un p•trat de latur• 100 în coltul din stânga-sus al ecranului.

Procedura Bar (ui,vi,uf,vf) realizeaz• •i umplerea (colorarea interiorului)

unui dreptunghi (semnifica•ia parametrilor fiind aceea•i). Un exemplu cu

ultimele dou• proceduri este dat în paragraful 14.3. Acestea sunt utilizate în

trasarea unei histograme în programul 14.8.

Pentru desenarea unui arc de cerc sau a unui sector de cerc, procedurile

Arc respectiv PieSlice solicit• urm•torii parametri:

- coordonatele centrului cercului,

- unghiul initial •i final exprimat în grade,

- raza cercului.

Procedura SetFillStyle(Model,Culoare) se utilizeaz• pentru umplerea unui

sector cu un Model dorit desenat într-o Culoare precizat•.

Page 10: 14 Elemente de Grafica in Pascal

142

Ca exemplu am ales desenarea unei diagrame circulare a precipita•iilor

zilnice dintr-o s•pt•mân•. Dac• se cunosc precipita•iile preci (i=1,7) se poate

calcula unghiul ini•ial •i final (în grade) pentru fiecare sectori astfel:

uii=si-1/sn*360 •i ufi=si/sn*360, unde si=prec1+prec2+...+preci (s0=0).

Program Diagrama_Circulara; {Programul 14.5}

Uses Graph;

Const

Prec: Array[1..7] of integer = (25,10,15,20,25,17,5);

Var Pd : string;

Ui,Uf, Suma, i, Gd,Gm: integer;

Begin

Gd:=Detect; Pd:=’F:\Soft\Tp\Bgi’ ;

InitGraph (Gd,Gm,Pd);

If GraphResult<>0 Then Begin

Write (’ Eroare InitGraph . ’); Readln; Halt (1)

End;

Suma:=0;

For i:=1 to 7 do Suma:=Suma+Prec[i];

Ui:=0;

For i:=1 to 7 do

Begin

Uf:=Ui+Round(Prec[i]*360/Suma);

SetFillStyle(i,i+8); {Umple cu modelul i in culoarea i+8}

PieSlice(GetMaxX div 2, GetMAxY div 2, {Coordonatele centrului}

Ui, Uf, 200 ); {Unghi initial •i final , Raza }

Ui:=Uf;

End;

Readln; CloseGraph

End.

Page 11: 14 Elemente de Grafica in Pascal

143

Procedura Ellipse (uo,vo, gi,gf, rx,ry) deseneaz• un arc de elips• cu centrul

(uo,vo) cuprins între unghiurile gi,gf exprimate în grade hexazecimale având axele

rx,ry.

Procedura FillEllipse (uo,vo, rx,ry) deseneaz• •i umple un arc de elips• cu

centrul (uo,vo) cuprins între unghiurile gi,gf, iar procedura Sector (uo,vo, gi,gf, rx,ry)

deseneaz• •i umple un sector de elips• precizat prin parametrii actuali a c•ror

semnifica•ie a fost deja prezentat•.

Pentru a tip•ri pe ecran un text în modul grafic se pot utiliza procedurile

OutText (Mesaj) sau OutTextxy (u,v,Mesaj). Mesaj-ul este o expresie de tip string

•i va fi tip•rit• începând din ultimul punct referit (în cazul procedurii OutText)

respectiv din punctul de coordonate u,v (OutTextxy).

Apelul OutTextxy(u,v,Mesaj) este echivalent cu MoveTo(u,v) urmat de

OutText(Mesaj). De exemplu:

OutTextxy(GetMaxX Div 2, GetMaxY Div 2,’Centrul ecranului’)

are ca efect tip•rirea începând din mijlocul ecranului a textului "Centrul

ecranului".

La tip•rirea textelor se pot utiliza anumite fonturi puse la dispozi•ia

programatorului, se poate preciza direc•ia de scriere (orizontal• sau vertical•)

precum •i dimensiunea caracterelor. Aceste trei elemente se pot preciza prin

apelul procedurii SetTextStyle (Font,Directie,Marime).

Dac• se dore•te o scalare a caracterelor care vor fi tip•rite, atunci se poate

realiza acest lucru prin apelul procedurii SetUserCharSize (MultX,DivX,

MultY,DivY).

În programul 14.8 din paragraful 14.3 sunt utilizate proceduri de tip•rire a

textelor.

Page 12: 14 Elemente de Grafica in Pascal

144

14.3. Desenarea pe ecran a figurilor din planul real.

În fereastra ecran [u1, u2] × [v1, v2] (ViewPort) putem reprezenta puncte

P(x,y) dintr-un domeniul [a,b] × [c,d] ⊂ R2 numit fereastr• real• (Window)

(vezi fig.14.3.1). Pentru a putea referi în instruc•iunile grafice un astfel de punct,

va trebui s• aplic•m o transformare de coordonate P(x,y) → M(u,v), care verific•

egalit••ile :

x-a u - u1

= b-a u2-u1 u:=Round((x-a)*(u2-u1)/(b-a))+u1

de unde rezult• y-d v- v1 v:=Round((y-d)*(v2-v1)/(c-d))+v1. = c-d v2-v1

Figura 14.3.1.

Pentru reprezentarea unei func•ii, a •i b pot fi capetele domeniului de

definitie, iar c •i d minimul respectiv maximul func•iei pe intervalul [a,b].

Dac• dorim s• referim un punct de coordonate reale din fereastra logic•

(Window) dup• declararea ferestrei ecran (ViewPort) atunci transformarea

P(x,y) → M(u’,v’), (x,y)∈[a,b]×[c,d],

necesar• pentru apelul unei rutine grafice este urm•toarea:

u’:=Round((x-a)*(u2-u1)/(b-a))

v’:=Round((y-d)*(v2-v1)/(c-d))

o

P1 (u1,v1)0

v1

v

v2

GetMaxY

M(u,v)

0 u1 u u2 GetMaxX

WiewPort

o

o

Ecranul

P2 (u2,v2)

y

c

Window

P(x,y) o

Planul real

a x b

d

Page 13: 14 Elemente de Grafica in Pascal

145

Aceast• transformare va fi efectuat• dup• declararea ferestrei fizice prin

procedura SetViewPort pentru c• u’ •i v’ reprezint• coordonate relative din

fereastra ecran (vezi ViewPort descris în paragraful precedent).

În exemplul urm•tor se traseaz• locul geometric al mijloacelor segmentelor

de lungime dat• cu capetele pe dou• semidrepte perpendiculare.

Program Puncte; {Programul 14.6}

Uses Graph; {Loc geometric}

Var Gd, Gm: integer;

Pd: string;

x, l: real;

u1, u2, v1,v2: integer;

a, b, c, d: real;

Function u (x:real):integer; {Transformarea}

Begin u:=Round((x-a)*(u2-u1)/(b-a)) End; {coord. x→ u}

Function v (y:real):integer; {Transformarea}

Begin v:=Round((y-d)*(v2-v1)/(c-d)) End; {coord. y→ v}

Begin

Gd:=Detect; Pd:=’F:\Soft\Tp\Bgi’;

InitGraph (Gd,Gm,Pd); l:=100; { l = Lung. Segm.}

a:=0; b:=l; c:=0; d:=l; {ViewPort}

u1:=200; v1:=100; u2:=400; v2:=300; {Window}

SetViewPort(u1,v1,u2,v2,ClipOn);

x:=0;

Repeat

PutPixel(u(x),v(0),Yellow); {Axa Ox}

PutPixel(u(x/2),v(Sqrt(Sqr(l)-Sqr(x))/2), White); {Mijloc}

PutPixel(u(0),v(Sqrt(Sqr(l)-Sqr(x))), Yellow); {Axa Oy}

x:=x+0.1;

Until x>l;

Readln; CloseGraph

End.

Page 14: 14 Elemente de Grafica in Pascal

146

În exemplul urm•tor vom trasa graficul mai multor func•ii în diferite

ferestre ecran. Pentru a trasa axele de coordonate vom utiliza procedura Line iar

graficul func•iei îl vom realiza prin segmente desenate cu procedura LineTo.

Datorit• faptului c• vom lucra în coordonate reale, va trebui ca la apelurile

procedurilor grafice s• executam transform•rile în coordonate ecran prin func•iile

u •i v .

Program Grafice_de_Functii; { Programul 14.7. Graficele func•iilor }

{$F+} Uses Graph; { f, g, s, c }

Type Functie=Function(x:real):real;

Var Gd, Gm:integer; Pd:string;

Function f(x:real):real; Begin f:=Exp(Abs(x)) End;

Function g(x:real):real; Begin g:=Ln(Abs(x)) End;

Function s(x:real):real; Begin s:=Sin(x) End;

Function c(x:real):real; Begin c:= Cos(x) End;

Procedure Grafic(f: Functie; a,b,: real; u1,v1, u2,v2: integer); {f:[a,b]→R}

Var x,p,y : real;

Function u(x:real):integer; Begin u:=Round((x-a)*(u2-u1)/(b-a))+u1 End;

Function v(y:real):integer; Begin v:=Round((y-d)*(v2-v1)/(c-d))+v1 End;

Begin

SetColor(White); MoveTo(u1,v1); {Fereastra fizica}

LineTo (u2,v1); LineTo(u2,v2);

LineTo (u1,v2); LineTo(u1,v1);

p:=3*(b-a)/(v2-v1); {p=pasul pentru x}

x:=a; c:=f(a); d:=f(a);

While x<=b do Begin y:=f(x); {Pentru x:=a,b,p executa}

If y<c Then c:=y Else If y>d Then d:=y { c /d = min / max(f(x)) }

x:=x+p End;

SetColor(DarkGray); {Axele de coordonate}

If a*b<0 Then Line(u(0),v(c),u(0),v(d)); {Axa Oy}

If c*d<0 Then Line(u(a),v(0),u(b),v(0)); {Axa Ox}

x:=a; MoveTo (u(x),v(f(x))); SetColor(LightBlue); {Trasare grafic}

While x<=b do Begin {Pentru x:=a,b,p executa}

LineTo(u(x),v(f(x))); x:=x+p End; {trasare(x,f(x))}

End;

Page 15: 14 Elemente de Grafica in Pascal

147

Begin

Gd:=Detect; Pd:=’F:\Soft\Tp\Bgi’; InitGraph (Gd,Gm,Pd);

Grafic (f, -Pi, Pi, 10, 10, 310, 150);

Grafic (g, -Pi, Pi,320, 10, 620, 150);

Grafic (s,-2*Pi,3*Pi, 10,160, 310, 340);

Grafic (c,-3*Pi, Pi,320,160, 620 ,340);

Readln; CloseGraph

End.

În programul urm•tor vom desena

o histogram• a temperaturilor medii

lunare dintr-un an, realizat• cu

dreptunghiuri de forma al•turat•:

Program Histograma_Temperaturi; {Programul 14.8}

Uses Graph;

Const Temp:Array[1..12] of integer= (-5,-10,-4,5,10,15,20,25,17,10,7,6); {Temp.}

Luna:Array[1..12] of string[3]= {Lunile anului}

(’Ian’,’Feb’,’Mar’,’Apr’,’Mai’,’Iun’,’Iul’,’Aug’,’Sep’,’Oct’,’Nov’,’Dec’);

Var a,b,c,d: real; {Window}

Pd: string;

u1,v1,u2,v2, i,j,Gd,Gm: integer; {ViewPort}

Function u(x:real): integer; Begin u:=Round((x-a)*(u2-u1)/(b-a)) End;

Function v(y:real): integer; Begin v:=Round((y-d)*(v2-v1)/(c-d)) End;

Begin

Gd:=Detect; Pd:=’F:\Soft\Tp\Bgi’; InitGraph(Gd,Gm,Pd);

SetColor(White);

u1:=20; v1:=20; u2:=GetMaxX-20; v2:=GetMaxY-20;

Rectangle(u1,v1, u2,v2); SetViewPort(u1,v1,u2,v2,ClipOn);

a:=-1; b:=15; d:=Temp[1]; c:=Temp[1];

For i:=2 to 12 do Begin

If Temp[i]>d Then d:=Temp[i] Else {Maximul func•iei}

If Temp[i]<c Then c:=Temp[i] End; {Minimul func•iei}

c:=c-2; d:=d+5;

Page 16: 14 Elemente de Grafica in Pascal

148

SetTextStyle(GothicFont,HorizDir,5);

OutTextxy(u(2),v(d),’Histograma temperaturilor’);

SetTextStyle(SansSerifFont,HorizDir,3); OutTextxy (u(13),v(0),’Luna’);

SetTextStyle(SansSerifFont,VertDir,3); OutTextxy (u(-1),v(d),’Temp.’);

SetColor(DarkGray); Line (u(0),v(c),u(0),v(d)); {Axa Oy}

Line (u(a),v(0),u(b),v(0)); {Axa Ox}

SetColor(LightBlue); {Trasare}

For i:=1 to 12 do Begin {histograma}

SetFillStyle(i Mod 6 +3,i+2); Bar(u(i),v(0),u(i+1),v(Temp[i]));

SetTextStyle(SmallFont,VertDir,5); OutTextxy (u(i+0.5),v(0),Luna[i]);

End; {For}

Readln; CloseGraph

End.

Reprezentarea grafic• a unor curbe remarcabile cum ar fi astroida care are

ca ecua•ie:

x2/3+y2/3=a2/3,

se poate realiza simplu dac• aceast• curb• este descris• de forma parametric• :

x=a·sin3t, y=a·cos3t (în programul Pascal a=Cst).

Program Graficul_unei_func•ii_Parametrice; {Programul 14.9}

Uses Graf, Graph; {x=X(t);y=Y(t)}

Const Marx=50; Mary=10; t1=0; t2=2*Pi; Cst=3; {Cst=a}

Function x(t:real): real;

Begin x:=Cst*Sqr(Sin(t))*Sin(t) End; {x(t)=a*Sin3t}

Function y(t:real): real;

Begin y:=Cst*Sqr(Cos(t))*Cos(t) End; {y(t)=a*Cos3t}

Var t, p, a,b, c,d : real;

Begin

SetColor(Yellow);

Rectangle(Marx-1,Mary-1,GetMaxX-Marx+1,GetMaxY-Mary+1);

View(Marx,Mary,GetMaxX-Marx,GetMaxY-Mary);

SetBkColor(Blue); ClearViewPort;

a:=x(t1); b:=x(t1); c:=y(t1); d:=y(t1); p:=(t2-t1)/200; t:=t1;

Page 17: 14 Elemente de Grafica in Pascal

149

Repeat {Det.Window}

If x(t)>b Then b:=x(t) Else If x(t)<a Then a:=x(t);

If y(t)>d Then d:=y(t) Else If y(t)<c Then c:=y(t);

t:=t+p

Until t>t2;

Window_(a,d,b,c); SetColor(DarkGray); {Set Window}

If c*d<=0 Then Line(u(a),v(0),u(b),v(0)); {Axa Ox}

If a*b<=0 Then Line(u(0),v(c),u(0),v(d)); {Axa Oy}

t:=t1; MoveTo(u(x(t)),v(y(t)));

SetColor(White);

Repeat {Graficul}

LineTo(u(x(t)),v(y(t))); t:=t+p

Until t>t2; Readln

End.

Pentru aceasta am utilizat unit-ul (Graf) urm•tor :

Unit Graf;

INTERFACE

Uses Graph;

Var Gd,Gm, {Var.pt.InitGraph}

Vl,Vr,Vd,Vt: integer; { ... ViewPort}

Wl,Wr,Wd,Wt: real; { ... Window }

Procedure View(l,t,r,d:integer); {(Left, Top),}

Procedure Window_(a,d,b,c:real); {(Rigth,Down)}

Function u(x:real):integer; {Transf. x→u}

Function v(y:real):integer; { ... y→v}

Procedure Linie(x1,y1,x2,y2: real); {Trasare segment}

Procedure Punct(x,y:real;Cul: Byte); {Desenare punct}

IMPLEMENTATION

Function u; Begin u:=Round((x-Wl)/(Wr-Wl)*(Vr-Vl)) End;

Function v; Begin v:=Round((y-Wt)/(Wd-Wt)*(Vd-Vt)) End;

Page 18: 14 Elemente de Grafica in Pascal

150

Procedure View;

Begin Vl:=l; Vr:=r; Vd:=d; Vt:=t; SetViewPort(l,t,r,d,ClipOff) End;

Procedure Window_;

Begin Wl:=a; Wr:=b; Wd:=c; Wt:=d End;

Procedure Linie;

Begin Line(u(x1),v(y1),u(x2),v(y2)) End;

Procedure Punct;

Begin PutPixel(u(x),v(y),Cul) End;

Begin

InitGraph (Gd,Gm,’C:\Tp\Bgi’);

If GraphResult<>GrOk Then Begin Write(’Err.Init Graph’); Readln; Exit

End {if}

End.

O problem• (de geometrie) de loc geometric o vom formula în continuare.

În triunghiul PQR se iau punctele E •i F pe laturile PQ respectiv PR

astfel încât PE=QF. Se cere s• se reprezinte grafic locul geometric al

mijloacelor segmentelor EF (N), dac• E •i F se plimb• pe laturile triunghiului

dat.

Program Loc_geometric_triunghi; {Programul 14.10}

Uses Crt, Graph, Graf; Const Marx=20; Mary=10;

Type Coord_Plan = Record x,y : real End;

Var m, pas, a,b, c,d : real; P,Q,R,E,F,N: Coord_Plan;

Procedure Rnd(Var L:Coord_Plan; v: integer); {Date L(x,y)}

Begin With L do Begin x:=v*100; y:=130*(1-Abs(v)) End End;

Function Min(a,b:real):real;

Begin If a<b Then Min:=a Else Min:=b End;

Function Max(a,b:real):real;

Begin Max:=a+b-Min(a,b) End;

Procedure Segment(A,B:Coord_Plan);

Begin Linie (A.x,A.y, B.x,B.y) End;

Page 19: 14 Elemente de Grafica in Pascal

151

Begin SetBkColor(Blue); ClearViewPort;

Rnd(P,0); Rnd(Q,-1); Rnd(R,1); SetColor(Yellow); {Triunghiul PQR}

Rectangle (Marx-1,Mary-1, GetMaxX-Marx+1,GetMaxY-Mary+1); {ViewPort}

View (Marx,Mary, GetMaxX-Marx,GetMaxY-Mary);

a:=Min(P.x,Min(Q.x,R.x)); b:=Max(P.x,Max(Q.x,R.x)); {Det.Window}

c:=Min(P.y,Min(Q.y,R.y)); d:=Max(P.y,Max(Q.y,R.y));

pas:=1/300; SetColor(DarkGray); Window_(a,d,b,c); {Def.Window}

If c*d<=0 Then Line(u(a),v(0),u(b),v(0)); {Axa Ox}

If a*b<=0 Then Line(u(0),v(c),u(0),v(d)); {Axa Oy}

SetColor(Yellow);

Linie(P.x,P.y, Q.x,Q.y); Linie(Q.x,Q.y, R.x,R.y); Linie(R.x,R.y, P.x,P.y); {∆.PQR}

m:=0; SetColor(LightBlue); SetWriteMode(XorPut);

Repeat {Pt. m=0,1,pas}

E.x:=m*P.x+(1-m)*Q.x; E.y:=m*P.y+(1-m)*Q.y; {E=Afin (PQ)}

F.x:=m*R.x+(1-m)*P.x; F.y:=m*R.y+(1-m)*P.y; {F=Afin (RP)}

N.x:=(E.x+F.x)/2; N.y:=(E.y+F.y)/2; {N=Mijl (EF)}

Segment(E,F); Delay(10); Segment(E,F); {Desenez apoi sterg segm. EF }

With N do Punct(x,y,Yellow); {Pun punct N}

m:=m+pas

Until m>1;

End.

Pentru a desena imagini definite recursiv am ales exemplul urm•tor :

1) 2) 3)

Programul Pascal care realizeaz• astfel de imagini utilizând limbaje de

comenzi, este prezentat în continuare. O astfel de figur• se poate defini printr-o

baz•, o regul• de dezvoltare (de cre•tere) •i num•rul de transform•ri aplicate

(vârsta în ani).

Page 20: 14 Elemente de Grafica in Pascal

152

Program Grafica_Recursiva; {Programul 14.11}

Uses Crt,Graph;

Var Suc,Pre: Array [’A’..’Z’] of char;

C : string; Gd,Gm : integer;

Procedure Succ_Pred;

Var p,i:integer;

Begin

p:=Length(C);

Suc[C[1]]:=C[2]; Pre[C[1]]:=C[p]; Suc[C[p]]:=C[1];

Pre[C[p]]:=C[p-1];

For i:=2 to p-1 do Begin Suc[C[i]]:=C[i+1]; Pre[C[i]]:=C[i-1] End

End;

Function Fi(x:Char): string; {Regula de dezvoltare}

Begin Fi:=x+Suc[x]+x+Pre[x]+x

End;

Function T(X:string): string; Var R:string; i:integer; {Cresterea cu un an }

Begin

If Length(X)=1 Then T:=Fi(X[1]) Else Begin

R:=’’; For i:=1 to Length(X) do R:=R+Fi(X[i]); T:=R End

End;

Function Tn(n:integer; X:string):string; {Cresterea in n ani}

Begin If n=1 Then Tn:=T(X) Else Tn:=Tn(n-1,T(X))

End;

Procedure Desen(S:string; x,y,l:integer); {Trasarea}

Var i:integer; {comenzilor}

Begin

MoveTo (x,GetMAxY-y);

For i:=1 to Length(S) do Begin

If S[i] in [’R’,’E’,’H’] Then x:=x+l Else If S[i] in [’L’,’F’,’G’] Then x:=x-l;

If S[i] in [’U’,’F’,’E’] Then y:=y+l Else If S[i] in [’D’,’G’,’H’] Then y:=y-l;

LineTo (x,GetMaxY-y)

End;

End;

Page 21: 14 Elemente de Grafica in Pascal

153

Begin

Gd:=Detect; InitGraph(Gd,Gm,’c:\tp\bgi’);

C:=’RULD’; {Dreapta=R,Sus=U} Succ_Pred; {Stanga=L,Jos=D}

Desen(Tn(1,’R’), 10,170,28); {Anul I, baza R}

Desen(Tn(2,’R’),200,170,14); {Anul II, " }

Desen(Tn(3,’R’),400,170, 7); {Anul III, " }

Readln; CloseGraph;

End.

Pentru a reprezenta o suprafa•• definit• de o func•ie z : [a,b]x[c,d] → R,

va fi necesar• o proiec•ie a punctelor din R3 în planul XOY. Vom considera o

proiec•ie paralel• dup• o direc•ie precizat• prin dou• elemente: r •i α, a•a cum se

poate vedea în figura urm•toare:

Pentru un punct oarecare P(x,y,z) va

trebui s• calculam coordonatele x’ •i y’ ale

proiec•iei acestuia dup• direc•ia precizat•.

Se poate observa c• triunghiul AOB este

asemenea cu triunghiul PDP’, de unde

rezult• c• 1/r=z/DP’, deci DP’=r⋅z . Pentru

c• x’=x+DP’·cosα •i y’=y+DP’·sinα rezult•

c• x'=x+r·z·cosα iar y’=y+r·z·sinα.

1

Urm•torul program Pascal, deseneaz• suprafa•a descris• de func•ia:

z:[-π,π]×[-π,π]→R, z(x,y)=sin x2+cos y2, aplicând o proiec•ie paralel• de

direc•ie (r,a) = (1, π/4).

Trasarea suprafe•ei se reduce la o problem• plan•. Pentru un punct x fixat,

iar y variabil din intervalul [c,d] se traseaz• graficul proiec•iei corespunz•toare

punctelor P(x,y,z(x,y)).

P’

(0,0,1)

α

α

r

P

y,y’

A

B

O

D E

z

x,x’

Page 22: 14 Elemente de Grafica in Pascal

154

Acest lucru se realizeaz• pentru mai multe puncte x alese din intervalul

[a,b] (n+1 puncte echidistante). Acela•i lucru se realizeaz• pentru y fix •i x

variabil, realizând astfel o imagine sub forma unei plase (ca în figura urm•toare).

Practic se reprezint• dou• •iruri de

curbe z(xi,y) •i z(x,yj), unde :

xi=a+i*(b-a)/n (i=0,1,...,n),

yj=c+j*(d-c)/m (j=0,1,...,m), iar n •i m

reprezint• fine•ea re•elei.

Program Suprafata; {Programul 14.12}

Uses Graph;

Var Vl,Vr, Vd,Vt, Wl,Wr, Wd,Wt, Gd,Gm, n,m : integer;

a,b, c,d, x,y, pas_x, pas_y, Ux,Uy, r,Alfa : real;

Function z(x,y:real):real; {z:[a,b]x[c,d]->R}

Begin z:=Sin(Sqr(x)+Sqr(y)); End;

Function Px(x,z:real):real; {Calculeaza x’}

Begin Px:=x+r*z*Cos(Alfa) End;

Function Py(y,z:real):real; {Calculeaza y’}

Begin Py:=y+r*z*Sin(Alfa) End;

Function u(x:real):integer;

Begin u:=Round((x-Wl) / (Wr-Wl)*(Vr-Vl))+Vl End;

Function v(y:real):integer;

Begin v:=Round((y-Wd)/(Wt-Wd)*(Vt-Vd))+Vd End;

Begin Gd:=Detect; InitGraph(Gd,Gm,’f:\soft\tp7\bgi’);

r:=1; Alfa:=Pi/4; n:=20; m:=20; {def.dir.pr. , def.diviz }

Vl:=100; Vr:=GetMaxX-100; Vt:=50; Vd:=GetMaxY-50; {ViewPort}

a:=-Pi; b:=Pi; c:=-Pi; d:=Pi; {dom.def.}

Pas_x:=(b-a)/n; Pas_y:=(d-c)/m;

Page 23: 14 Elemente de Grafica in Pascal

155

Wl:=Px(a,z(a,c)); Wr:=Px(a,z(a,c)); {Max,Min/x’,y’ (Window) }

Wd:=Py(c,z(a,c)); Wt:=Py(c,z(a,c));

x:=a; Repeat y:=c;

Repeat Ux:= Px(x,z(x,y));

If Ux<Wl Then Wl:=Ux Else If Ux>Wr Then Wr:=Ux;

Uy:= Py(y,z(x,y));

If Uy<Wd Then Wd:=Uy Else If Uy>Wt Then Wt:=Uy;

y:=y+pas_y

Until y>d; x:=x+pas_x

Until x>b; SetColor (LightGray);

Line (u(Px(a,0)),v(Py(0,0)), u(Px(b,0)),v(Py(0,0))); {Axe}

Line (u(Px(0,0)),v(Py(c,0)), u(Px(0,0)),v(Py(d,0)));

Line (u(Px(0,0)),v(Py(0,0)), u(Px(0,z(a,c))), v(Py(0,z(a,c))));

Circle(u(Px(0,0)),v(Py(0,0)),2); {originea}

x:=a; SetColor(12); {x fixat, y variabil}

Repeat y:=c; {Pt. x=a,b,pas_x : muta. P’(x’,y’)}

MoveTo (u(Px(x,z(x,y))), v(Py(y,z(x,y)))); y:=y+pas_y;

Repeat {Pt. y=c,d,pas_y : tras. P’(x’,y’)}

LineTo (u(Px(x,z(x,y))), v(Py(y,z(x,y)))); y:=y+pas_y

Until y>d; x:=x+pas_x

Until x>b;

y:=c; SetColor(13); {y fixat, x variabil}

Repeat x:=a; {Pt. y=c,d,pas_y : muta. P’(x’,y’)}

MoveTo (u(Px(x,z(x,y))), v(Py(y,z(x,y))));

x:=x+pas_x;

Repeat {Pt. x=a,b,pas_x : {tras. P’(x’,y’)}

LineTo (u(Px(x,z(x,y))), v(Py(y,z(x,y))));

x:=x+pas_x

Until x>b; y:=y+pas_y

Until y>d;

Readln; CloseGraph

End.