Lucrarea nr.
2
A.Descriere
1. Marimi
caracteristice
Cea mai mica unitate grafica
pe care o putem controla din zona de desenare poarta denumirea de pixel. Zona
de desenare poate fi considerata ca o matrice bidimensionala de pixeli.
Accesul la un pixel se face prin specificarea unei perechi de valori intregi
(dcx, dcy) care precizeaza pozitia acestuia in matricea zonei de desenare,
relativ la un sistem de coordonate avand originea in coltul stanga sus. Acest
spatiu de adresare se numeste spatiu dispozitiv (sau spatiu ecran) si
defineste rezolutia grafica a acestuia.
Zona de desenare este
caracterizata prin:
- numarul maxim de pixeli pe
orizontala npo
- numarul maxim de pixeli pe
verticala npv
Considerand ca lungimea fizica
a zonei de desenare (in mm) este lung, iar inaltimea fizica (in mm)
este inalt, din aceste patru marimi pot fi deduse o serie de marimi
derivate, care prezinta interes pentru proiectantul pachetelor de
programepentru grafica pe calculator:
rez_o = npo / lung
- dimensiunea unui punct pe
orizontala:
dim_po = lung / npo
rez_v = npv / inalt
- dimensiunea unui punct pe
verticala:
dim_pv = inalt / npv
- numarul total de puncte
adresabile (rezolutia):
rez = npv * npo
- rezolutia bidimensionala:
rez_a = re / (lung * inalt)
Rezolutiile verticala,
orizontala si bidimensionala reprezinta rezolutiile fizice ale dispozitivelor
grafice si presupun masurari fizice ale distantelor. Mai multe echipamente
pot avea aceeasi rezolutie grafica, dar cu totul alte rezolutii fizice.
In general dimensiunile
punctelor pe verticala, respectiv pe orizontala sunt diferite (dim_po
<> dim_pv). Ca
urmare, punctele din spatiul imagine au o anumita suprafata finita, iar forma
lor este dreptunghiulara.
Se defineste raportul de
aspect grafic ca raportul
aspect = dim_po / dim_pv
iar raportul de aspect fizic
aspect_fiz = inalt / lung
Este de dorit ca echipamentele
grafice sa aiba puncte "patrate", adica un raport de aspect grafic
cat mai apropiat de 1. Un patrat vizualizat pe un astfel de achipament grafic
va fi intr-adevar reprezentat de un patrat in spatiul imagine. In general
insa patratul apare sub forma de dreptunghi, deoarece echipamentele grafice
poseda, de cele mai multe ori, un raport de aspect grafic diferit de 1.
2. Sisteme de
coordonate
Coordonate (dcx,dcy) se numesc
coordonate hardware sau coordonate ale dispozitivului.
Desigur,
0 <= dcx <= npo1 = NPO-1
0 <= dcy <= npv1 = NPV-1
Domeniul de variatie al
valorilor dcx, dcy este diferit pentru diversele dispozitive grafice. Pentru
a asigura o tratare unitara, independenta de dispozitivul grafic, in scopul
asigurarii portabilitatii aplicatiilor, s-au introdus coordonatele dispozitiv
normalizate (NDC), care sunt valori reale in domeniul [0,1].
0 <= ndcx <= 1
0 <= ndcy <= 1
Punctul (ndcx=0;ndcy=0) poate
corespunde punctului (dcx=0;dcy=0), iar punctul (ndcx=1;ndcy=1) poate
corespunde punctului (dcx=npo1;dcy=npv1). Utilizand coordonatele normalizate,
descrierea obiectelor grafice la nivelul aplicatiei va fi independenta de
dispozitivele grafice particulare. Transformarea intre cele doua sisteme de
coordonate se poate face simplu, prin functiile liniare
dcx = round (ndcx * npo1)
dcy = round (ndcy * npv1)
La nivelul aplicatiei,
elementele grafice se definesc intr-un spetiu de coordonate carteziene al
utilizatorului (spatiul utilizatorului). Acest spatiu poate fi spatiul
euclidian (R2 sau R3). In cazul spatiului R2,
obiectele se precizeaza prin coordonatele carteziene (x,y), cu valori reale.
Desigur, pentru a reprezenta pe ecran un obiect din spatiul utilizator, este
necesara transformarea coordonatelor sale in coordonate din spatiul imagine:
(x,y) -> (dcx,dcy). In general, coordonate (xi,yi)
ale punctelor din scena grafica pot fi incadrate intr-un spatiu
dreptunghiular
xmin <= xi <= xmax
ymin <= yi <= ymax
Acest domeniu dreptunghiular
din spatiul obiect se numeste fereastra (window). Continutul sau va fi
transpus in ecran intr-un domeniu dreptunghiular din spatiul dispozitiv numit
port de vedere (viewport), utilizand o serie de transformari de
coordonate. In orice moment, este necesar sa fie definite o fereastra si un
port de vedere, definite de programul de aplicatie si retinute in structurile
interne ale pachetului grafic.
B. Implementare
In cadrul lucrarii se vor
implementa proceduri si functii necesare pentru realizarea urmatoarelor
operatii:
- activarea unei ferestre
grafice
- definirea ferestrelor
- definirea porturilor de
vedere
- corectia aspectului grafic
- transformarea coordonatelor
utilizator in coordonate ecran
- trasarea segmentelor de
dreapta in spatiul utilizator.
Aceste operatii de baza se
gasesc la nivelul cel mai scazut intr-o abordare ierarhica a structurii unui
pachet grafic. Ele se vor include in modulul G2Dnucleu.
/*======================================================================*/
/* G2Dnucleu.h */
/*======================================================================*/
extern void set_window (double x1, double y1, double x2, double y2);
extern void set_viewport (int x1, int y1, int x2, int y2, int cadru);
extern void punct_2d (double x, double y);
extern void linie_2d (double x1, double y1, double x2, double y2);
extern void InitG2Dnucleu (void);
/*======================================================================*/
/* End of G2Dnucleu.h */
/*======================================================================*/
/*======================================================================*/
/* G2Dnucleu.c */
/*======================================================================*/
#include <stdio.h>
#include <Xm/Form.h>
#include <Xm/DrawingA.h>
#include <Xm/MwmUtil.h>
#include <X11/cursorfont.h>
#include "Graph.h"
#include "G2Dnucleu.h"
/* Structuri de Date Private -------------------------------------------*/
typedef struct _window_type
{
double xmin, ymin;
double xmax, ymax;
} window_type;
typedef struct _viewport_type
{
int xmin, ymin;
int xmax, ymax;
} viewport_type;
static int npo, npv;
static window_type window;
static viewport_type viewport;
/* Prototipuri Private -------------------------------------------------*/
static void user_to_out (double x, double y, int *dcx, int *dcy);
static void user_to_ndc (double x, double y, double *ndcx, double *ndcy);
static void ndc_to_out (double ndcx, double ndcy, int *dcx, int *dcy);
/* Rutine Publice ------------------------------------------------------*/
void
InitG2Dnucleu ()
{
npo = GetmaxX + 1;
npv = GetmaxY + 1;
set_window (-100., -100., 100., 100.);
set_viewport (0, 0, npo-1, npv-1, FALSE);
} /* InitG2Dnucleu */
void
set_window (double x1, double y1, double x2, double y2)
{
/* Definitia procedurii set_window */
} /* set_window */
void
set_viewport (int x1, int y1, int x2, int y2, int cadru)
{
/*
* Definitia procedurii set_viewport.
* Deoarece originea este in coltul stanga sus, se va stabili
* sistemul de coordonate cu originea in coltul din stanga jos:
*/
viewport.ymin = npv - 1 - y1;
viewport.ymax = npv - 1 - y2;
viewport.xmin = x1;
viewport.xmax = x2;
/*
* Daca valorile coordonatelor depasesc limitele spatiului ecran,
* se vor modifica cu valorile limita.
*/
} /* set_viewport */
void
punct_2d (double x, double y)
{
/* Definitia procedurii punct_2d */
} /* punct_2d */
void
linie_2d (double x1, double y1, double x2, double y2)
{
/* Definitia procedurii linie_2d */
} /* linie_2d */
/* Rutine Private ------------------------------------------------------*/
/*
* Conversie coordonate utilizator in coordonate ecran
*/
static void
user_to_out (double x, double y, int *dcx, int *dcy)
{
double ndcx, ndcy;
user_to_ndc (x, y, &ndcx, &ndcy);
ndc_to_out (ndcx, ndcy, dcx, dcy);
} /* user_to_out */
static void
user_to_ndc (double x, double y, double *ndcx, double *ndcy)
{
*ndcx = (x - window.xmin) / (window.xmax - window.xmin);
*ndcy = (y - window.ymin) / (window.ymax - window.ymin);
} /* user_to_ndc */
static void
ndc_to_out (double ndcx, double ndcy, int *dcx, int *dcy)
{
*dcx = (viewport.xmax - viewport.xmin) * ndcx + viewport.xmin;
*dcy = (viewport.ymax - viewport.ymin) * ndcy + viewport.ymin;
} /* ndc_to_out */
/*======================================================================*/
/* End of G2Dnucleu.c */
/*======================================================================*/
Download G2Dnucleu.h,
G2Dnucleu.c.
C. Aplicatii
1. Elaborati modulul G2Dnucleu.
2. Desenati un poligon regulat cu n laturi, avand raza cercului circumscris
p si centrul in punctul de coordonate utilizator C(x,y). Definiti corespunzator un port de vedere si o fereastra.
3. Scrieti o rutina care deseneaza un cerc prin aproximarea lui cu un
poligon regulat cu n=50 laturi si incorporati aceasta rutina in modulul
G2Dnucleu.
4. Desenati in conditiile de la punctul 2 un poligon regulat stela cu n
laturi.
5. Stabiliti corespunzator un window si un viewport. Reluati punctele 1-4
definind figurile in spatiul obiect.
6. Modificati limitele window-ului si refaceti figurile 1-4 observand
marirea/micsorarea imaginii (zoom);
7. Stabiliti un window si 4 viewporturi care se pot incadra in fereastra de
desenare. Reprezentati in fiecare din cele 4 viewporturi cate o figura din cele definite la 1-4.
8. Generati perechi aleatoare de puncte utilizand functia random din
stdlib.h. Pentru acele perechi de puncte care se incadreaza in fereastra curenta, desenati segmente de dreapta utilizand rutina linie_2d.
|