unitgraph

24
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 matrice de puncte (pixeli). 4 0 u Dmx  0 v Dmy  o P(u,v)

Upload: costin-nita

Post on 08-Apr-2018

219 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: UNITGRAPH

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)

Page 2: UNITGRAPH

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

Page 3: UNITGRAPH

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

Page 4: UNITGRAPH

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

Page 5: UNITGRAPH

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

Page 6: UNITGRAPH

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

Page 7: UNITGRAPH

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

Page 8: UNITGRAPH

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

Page 9: UNITGRAPH

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

Page 10: UNITGRAPH

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

Page 11: UNITGRAPH

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

Page 12: UNITGRAPH

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

 

Page 13: UNITGRAPH

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

Page 14: UNITGRAPH

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

Page 15: UNITGRAPH

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

Page 16: UNITGRAPH

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

Page 17: UNITGRAPH

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

Page 18: UNITGRAPH

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

Page 19: UNITGRAPH

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

Page 20: UNITGRAPH

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

Page 21: UNITGRAPH

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

a x b

yc

 P(x,y)o

d

 

Page 22: UNITGRAPH

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

Page 23: UNITGRAPH

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

Page 24: UNITGRAPH

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