unitgraph
TRANSCRIPT
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 1/24
1. Elemente de grafică 2_D
1.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.
În modul grafic, ecranul poate fi
considerat ca fiind format dintr-o matricede puncte (pixeli).
4
0 u Dmx
0
v
Dmy
o P(u,v)
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 2/24
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).
1.2. Instrucţiuni grafice .
5
WiewPort
P1(u1,v1) v1
v2
o
o P2(u
2,v
2)
u1
u2
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 3/24
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}
Begin
Gd:=Detect; {Selectare automata}
Pd:='F:\Soft\Tp\Bgi'; {Calea fisierlui EGAVGA.Bgi}
InitGraph (Gd,Gm,Pd); {Selectarea modului grafic}
6
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 4/24
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 cerccu 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:
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
7
o
o P2(u
2,v
2)
0 ≤ u1
< u2
< GetMaxX
0 ≤ v1 < v2 < GetMaxY
WiewPort
0
v1
v2
GetMaxY
P1(u
1,v
1)
0 u1
u2
GetMaxX
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 5/24
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;
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)
8
o
v1
v
M(u’,v’)
u1
u
u’ = u-u1
v’ = v-v1
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 6/24
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;
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
9
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 7/24
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 ozonă 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;
BeginCv:=GetPixel(u,v); Umplere(u,v);
End;
BeginGd:=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);
10
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 8/24
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 ,u f ,v f ) trasează în culoarea curentă segmentul ce are ca
extremităţi punctele (ui ,vi) şi (u f ,v f ). 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 (u f ,v f ) care
desenează segmentul determinat de ultimul punct referit (punctul curent) şi
punctul de coordonate (u f ,v f ) precizat prin parametrii procedurii LineTo. Apelul
Line(ui ,vi ,u f ,v f ) este echivalent cu MoveTo(ui ,vi) urmat de LineTo(u f ,v f ). În
paragraful următor (1.3) este dat un exemplu de reprezentare grafică a unor
funcţii în care sunt utilizate procedurile Line şi LineTo (programul 1.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).
Program Desen; Uses Graph, Crt; {Programul 1.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
11
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 9/24
'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 ,u f ,v f ) desenează dreptunghiul determinat de
vârfurile diagonal opuse (ui ,vi) şi (u f ,v f ). 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 ,u f ,v f ) realizează şi umplerea (colorarea interiorului)unui dreptunghi (semnificaţia parametrilor fiind aceeaşi). Un exemplu cu
ultimele două proceduri este dat în paragraful 1.3. Acestea sunt utilizate în
trasarea unei histograme în programul 1.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ă.
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 sector i astfel : uii=si-
1/sn*360 şi uf i=si/sn*360, unde si=prec1+prec2+...+preci (s0=0).
Program Diagrama_Circulara; {Programul 1.5}
Uses Graph;
Const
Prec: Array[1..7] of integer = (25,10,15,20,25,17,5);
Var Pd : string;
12
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 10/24
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.
Procedura Ellipse (uo ,vo , g i ,g f , r x ,r y ) desenează un arc de elipsă cu centrul
(uo ,vo) cuprins între unghiurile g i ,g f exprimate în grade hexazecimale având axele
r x ,r y.
Procedura FillEllipse (uo ,vo , r x ,r y ) desenează şi umple un arc de elipsă cucentrul (uo ,vo) cuprins între unghiurile g i ,g f , iar procedura Sector (uo ,vo , g i ,g f , r x ,r y )
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
13
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 11/24
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 1.8 din paragraful 1.3 sunt utilizate proceduri de tipărire a
textelor.
1.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 ] ⊂ R 2 numit fereastră reală (Window)
(vezi fig.1.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.
14
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 12/24
──── = ──── c-d v2-v1
Figura 1.3.1.
Pentru reprezentarea unei funcţii, a şi b pot fi capetele domeniului dedefinitie, 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))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 1.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}
15
o
P1(u
1,v
1)
0
v1
v
v2
GetMaxY
M(u,v)
0 u1
u u2
GetMaxX
WiewPort
o
o
Ecranul
P2(u
2,v
2)
yc
Window
P(x,y)o
Planul real
a x b
d
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 13/24
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.
Î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 1.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 }
16
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 14/24
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;
BeginGd:=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 1.8}
Uses Graph;
17
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 15/24
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;
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ă :
18
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 16/24
x=a·sin3t, y=a·cos3t (în programul Pascal a=Cst ).
Program Graficul_unei_funcţii_Parametrice; {Programul 1.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;
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}
19
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 17/24
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;
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.
20
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 18/24
Program Loc_geometric_triunghi; {Programul 1.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;
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;
21
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 19/24
Readln
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 decomenzi, 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).
Program Grafica_Recursiva; {Programul 1.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 BeginR:=''; For i:=1 to Length(X) do R:=R+Fi(X[i]); T:=R End
22
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 20/24
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;
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.
1.4. Interpretarea imaginilor de pe ecran.
În acest paragraf ne interesează cum putem afla coordonatele reale ale
unui punct precizat printr-un pixel de pe ecran, deci problema inversă şi anume
transformarea din fereastra ecran în cea reală ( M(u,v) → P(x,y), vezi figura
1.3.1). Acest lucru este necasar în situaţia în care avem reprezentat pe ecran un
23
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 21/24
desen şi ne interesează, de exemplu, coordonatele aproximative ale unui punct pe
care îl precizăm cu ajutorul dispozitivului de mouse. Aceste transformări care se
pot deduce uşor tot din proporţiile prezentate în primul paragraf sunt următoarele
(vezi figura 1.4.1) :
x:=(u-u1 )/(u2-u1 )*(b-a)+a ( = u-1 )
y:=(v-v1 )/(v2-v1 )*(c-d)+d ( = v-1 )
Figura 1.4.1.
Următorul program trasează graficul unei funcţii reale, pe un interval dat
[a,b] apoi tipăreşte coordonatele unor puncte de pe grafic precizate cu ajutorul
cursorului de mouse.
Programul utilizează unit-ul Graf , pentru desenarea graficului funcţiei şi
unit-ul MouseGra pentru utilizarea mouse-ului (prezentate în continuarea
programului). Programul apelează procedura MInit pentru iniţializarea mouse-
ului, procedurile MOff şi MOn care permit afişarea respectiv ascunderea
cursorului de mouse, funcţiile MStanga şi MDreapta pentru a detecta apăsarea
de unui buton de mouse (din stânga respectiv din dreapta), precum şi funcţia
MgX pentru a cunoaşte coordonata de coloană a cursorului de mouse. Funcţia
u_1 returnează coordonata reală corespunzătoare.
Program Valori_pe_graficul_unei_functii; {$F+} { f:[a,b]→ R }
Uses Graf, Graph, MouseGra;
Type Functie = Function (x:Real) : Real;
Var x,y : Real; sx,sy:String;
Function f (x:Real) : Real; Begin f:=Sin(x) End;
Procedure Grafic (f:Functie; a,b:Real); Const Mar=30; Var x,p, c,d:Real;
Begin InitGraf; SetBkColor(Blue); ClearViewPort;
SetColor(LightGray); Rectangle(0,0,GetMaxX,GetMaxY);
SetColor(LightBlue); Rectangle(Mar,Mar,GetMaxX-Mar,GetMaxY-Mar);
24
v1
v
v2
u
1u u
2
a x b
yc
P(x,y)o
d
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 22/24
View (Mar,Mar,GetMaxX-Mar,GetMaxY-Mar);
a:=-2*Pi; b:=4*Pi; c:=f(a); d:=f(a);
p:=(b-a)/(GetMaxX-2*Mar)*3; x:=a;
Repeat If f(x)>d Then d:=f(x) Else If f(x)<c Then c:=f(x); x:=x+p
Until x>b;Window_ (a,d*1.1,b,c*1.1); SetColor(LightGray);
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 }
x:=a; MoveTo(u(x),v(f(x))); SetColor(White);
Repeat LineTo(u(x),v(f(x))); x:=x+p Until x>b;
End;
Begin Grafic (f,-1,4); MInit ; MOn; SetColor(Yellow); SetLineStyle(1,1,1);
Repeat
If MStanga Then Begin MOff;
x:=u_1(MgX); y:=f(x); Circle (u(x),v(y),2);
Str (x:5:2,sx); OutTextXY(u(x),v(0)+10,sx);
Str (y:5:2,sy); OutTextXY(u(0)-50,v(y),sy);
Linie(x,0,x,y); Linie(0,y,x,y); MOn End;
Repeat Until Not MStanga
Until MDreapta
End.
Unit Graf;
Interface Uses Graph;
Procedure View (l,t,r,d:Integer);
Procedure Window_(a,d,b,c:Real);
Function u (x : Real) : Integer;Function v (y : Real) : Integer;
Function u_1 (u : Word) : Real;
Function v_1 (v : Word) : Real;
Procedure Linie (x1,y1,x2,y2:Real);
Implementation
Var Gd,Gm, Vl,Vr,Vd,Vt:Integer; Wl,Wr,Wd,Wt:Real;
Function u; Begin u :=Round((x-Wl)/(Wr-Wl)*(Vr-Vl)) End;
Function v; Begin v :=Round((y-Wt)/(Wd-Wt)*(Vd-Vt)) End;
25
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 23/24
Function u_1; Begin u_1:= Wl + (u-Vl)/(Vr-Vl)*(Wr-Wl) End;
Function v_1; Begin v_1:= Wt + (v-Vt)/(Vd-Vt)*(Wd-Wt) End;
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 InitGraf; Begin Gd:=Detect;
InitGraph (Gd,Gm,'C:\Bp\Bgi') End;
End.
Unit MouseGra ; (* {$O+,F+} *)
Interface Uses Dos;Procedure MInit ; Function MOk : Boolean ; {Rez. in Tes}
Procedure MOn; Procedure MOff ;
Function MStanga:Boolean;
Function MDreapta : Boolean ;
Function MgX : Word;
Function MgY : Word ;
Procedure MgXY (X,Y: Word) ; Procedure MgD (X1,Y1,X2,Y2: Word) ;
Implementation
Var Tes : Boolean; R : Registers;
Procedure MInit; Begin R.AX:= 0; Intr($33,R); { Iniţializare Mouse }
Tes:=R.AX<>0; End; { Rezultatul în Tes}
Function MOk; Begin MOk:=Tes End; {mouse Ok}
Procedure MOn; Begin R.AX:= 1; Intr($33,R); End; {mouse On}
Procedure MOff; Begin R.AX:= 2; Intr($33,R); End; {mouse Off}
Function MStanga:Boolean; { buton Stânga} Begin R.AX:=3; Intr($33,R); MStanga:=R.BX And 1 = 1 End;
Function MDreapta : Boolean; {buton Dreapta}
Begin R.AX:=3; Intr($33,R); MDreapta:=R.BX And 2 = 2 End;
Function MgX : Word; {Where X}
Begin R.AX := 3; Intr($33,R); MgX := R.CX End;
Function MgY : Word; {Where Y}
Begin R.AX := 3; Intr($33,R); MgY := R.DX End;
Procedure MgXY (X,Y: Word); {GotoXY} Begin R.CX:=X; R.DX:=Y; R.AX:=4; Intr($33,R) End;
26
8/7/2019 UNITGRAPH
http://slidepdf.com/reader/full/unitgraph 24/24
Procedure Mgd (X1,Y1, X2,Y2: Word); {Window}
Begin R.CX:=X1; R.DX:=X2; R.AX:=7; Intr($33,R);
R.CX:=Y1; R.DX:=Y2; R.AX:=8; Intr($33,R) End;
End.
27