[Graphics Lab Logo Image]  

Home  Up  Feedback  Contents  Search 

Lucrarea nr.11: Tehnici pentru Reprezentarea Grafica a Obiectelor 3D

[ Prev ] Lucrarea 11 [ Next ]

[Under Construction]

Descriere

Implementare

Aplicatii

  

A.Descriere

1. Proiectii

Mediile pe care se pot reprezenta imaginile grafice sunt bidimensionale : ecranul unui display, plotterul, imprimanta. Atunci cand dorim sa vizualizam un obiect 3D este necesara transformarii reprezentarii tridimensionale a obiectului intr-o forma bidimensionala ce poate fi redata pe mediul de reprezentare. Aceasta transformare poarta denumirea de proiectie.

O proiectie poate fi comparata cu umbra pe care o "arunca" un obiect asupra unui perete. Modelul matematic utilizat pentru determinarea proiectiei obiectului este insa mai simplu, pentru ca in grafica pe calculator atat obiectul cat si “peretele” pe care se obtine umbra sunt imaginare. Vom calcula proiectiile tuturor punctelor obiectului, unele din acestea fiind insa invizibile in realitate. Indepartarea acestor puncte este o problema aparte in cadrul graficii asistate de calculator.

Spatiul tridimensional in care este definit un obiect real poarta denumirea de spatiu obiect si poate fi asimilat cu lumea inconjuratoare. Spatiul bidimensional pe care se proiecteaza obiectul poarta denumirea de spatiu imagine si poate fi asimilat cu ecranul calculatorului.

Un obiect este format dintr-o infinitate de puncte. Calcularea proiectiei fiecarui punct este practic imposibila. Tipurile de proiectii pe care le vom considera in continuare au insa au proprietatea ca segmentele de dreapta 3D se proiecteaza in segmente de dreapta 2D. Ca urmare proiectia unui segment de dreapta poate fi obtinuta proiectand cele 2 capete ale sale din spatiul obiect si apoi conectand cele doua puncte obtinute in spatiul imagine.

Proiectiile geometrice plane ale obiectelor sunt obtinute prin intersectia unor drepte numite proiectori cu un plan numit plan de proiectie. Proiectorii sunt drepte duse dintr-un punct arbitrar numit centru de proiectie, prin fiecare punct al obiectului. Daca centrul de proiectie este plasat intr-un punct finit al spatiului rezultatul este o proiectie perspectiva. Daca centrul de proiectie este localizat la infinit, toti proiectorii sunt paraleli iar rezultatul este o proiectie paralela.

Pentru dezvoltarea ecuatiilor care descriu o proiectie este necesara introducerea unui sistem de coordonate in spatiul obiect. Vom considera planul ecranului paralel cu planul xOy al sistemului de axe de coordonate. Pentru axa Oz vom alege sensul dinspre observator, perpendicular pe planul xOy adica un sistem cartezian triortogonal stang:

Coordonatele unui punct oarecare P vor fi (x,y,z) sau in coordonate omogene (x,y,z,1).

Vom presupune ca centrul de proiectie (pozitia ochiului observatorului) este fix plasat pe semiaxa Oz negativa iar planul de proiectie perpendicular pe axa Oz (analog pentru proiectiile pe planele yOz si zOx ).

1.1  Proiectia paralela

Proiectia paralela simuleaza umbra aruncata pe un perete de un obiect iluminat de o sursa de lumina aflata la mare distanta de aceasta (centrul de proiectie se afla la infinit). Proiectia paralela a unui punct P(x,y,z) din spatiul obiect se obtine trasand o dreapta cu o anumita directie in spatiu prin acest punct. Intersectia acestei drepte cu planul z=0 este proiectia punctului P. Unghiul dreptei de proiectie determina proiectiei in planul xOy care este si planul ecranului.

In forma parametrica un proiector pe directia v(xp,yp,zp) are ecuatiile:

	xu = x + u*xp
	yu = y + u*yp
	zu = z + u*zp

Punctele din planul xOy au zu=0 deci u= -z/zp iar coordonatele proiectiei vor fi:

	xp1 = x - z/zp*xp
	yp1 = y - z/zp*yp
	zp1 = 0

Daca vectorul de proiectie este normal planului xOy avem xp=0, yp=0, zp=1 deci:

	xp1 = x
	yp1 = y
	zp1 = 0

Aceste ecuatii definesc proiectia ortografica.

Proiectia ortografica nu modifica lungimea liniilor paralele cu planul de proiectie. Punctele din spatiul obiect care au aceleasi coordonate x si y au in aceeasi proiectie.

Daca dreptele de proiectie nu este paralela cu axa Oz se obtine proiectia oblica. Un exemplu este umbra aruncata pe pamant de lumina solara. Aceasta proiectie se utilizeaza pentru desenarea umbrelor pe ecran dar nu si pentru corpuri deoarece ea produce distorsiuni nenaturale ale imaginilor.

Proiectia paralela cu directiile xp, yp nenule va genera o proiectie oblica. Coordonatele proiectiei unui punct vor fi deci:

	xobl = x - z/zp*xp
	yobl = y - z/zp*yp
	zobl = 0

Un caz special de proiectie oblica este proiectia cabinet. Aceasta utilizeaza un vector de proiectie ce formeaza cu axa Oz un unghi de aproximativ 26.6º. Dreptele paralele cu axa Oz vor fi proiectate dupa drepte la un unghi de 30º cu axa Ox. Directia proiectorilor este in acest caz:

	xp = 0.433, yp = 0.25 zp = -1

1.2 Proiectia perspectiva

Proiectia perspectiva produce imagini mult mai apropiate de modul in care sunt percepute obiectele reale de ochiul omului.

Centrul de proiectie corespunde pozitiei ochiului observatorului. Vom presupune ca centrul de proiectie se afla in fata ecranului si este specificat in acelasi sistem de coordonate pe care il utilizam pentru descrierea obiectelor. Pozitia centrului de proiectie nu are nici o legatura cu distanta fizica reala a observatorului fata de ecran. Ecranul insusi se presupune a fi in punctul z=0 al sistemului de coordonate xOyz. Obiectul este astfel descris incat el sa fie pozitionat in spatele ecranului, asa cum este vazut de observator.

Distanta centrului de proiectie fata de ecran (z=0) se va da ca un numar pozitiv d. Coordonatele centrului vor fi (0,0,-d).

Un punct P(x,y,z) se proiecteaza in punctul P’(xps,yps) cu :

	xps = d*x/(d+z)
	yps = d*y/(d+z)
	zps = 0

Presupunerea ca centrul proiectiei se afla pe axa Oz nu este restrictiva, pentru ca formulele pentru o proiectie perspectiva cu un alt centru si pe un alt plan pot fi obtinute prin aplicarea transformarilor de vedere. Transformarile planului de vedere vor aduce intotdeauna centrul de proiectie pe axa Oz. Este important insa ca planul de proiectie sa fie perpendicular pe axa Oz pentru a obtine formule simple. Ecranul calculatorului se considera a fi parte a planului de proiectie. Zona rectangulara a ecranului pe care dorim sa reprezentam o imagine este un port de vedere. Daca dorim sa aflam zona din spatiul ce poate fi reprezentat in portul de vedere, va trebui sa trasam drepte din centrul de proiectie prin cele 4 colturi ale zonei ecran. Aceste drepte vor constitui muchiile asa numitei piramide de vedere. Varful acestei piramide va fi centrul de proiectie.

2. Primitive grafice 3D

Elementele grafice 3D pe care le vom utiliza sunt: punctul, segmentul de dreapta, poligonul.

Aceste elemente grafice definite in 3D vor fi reprezentate in spatiul imagine 2D utilizand una din metodele de proiectie reprezentate.

Fiecarui element grafic va corespunde o procedura de reprezentare numita primitiva grafica.

Aceasta procedura va converti coordonatele 3D in coordonate in planul 2D utilizand procedura de proiectie dupa care va apela, in general, primitivele grafice corespunzatoare din pachetul grafic 2D, G2D_NUCLEU. De exemplu:

procedure linie_3D(x1,y1,z1, x2,y2,z2 : real);
var xp1,yp1,xp2,yp2 : real;
begin
    proiecteaza(x1,y1,z1,xp1,yp1);
    proiecteaza(x2,y2,z2,xp2,yp2);
    linie_2d(xp1,yp1,xp2,yp2);
end;

De remarcat ca apelul procedurii linie_2d asigura totodata sectionarea (clipping) relativ la fereastra definita in spatiul imagine (ecran) bidimensional.

Trasarea curbelor 3D se va realiza dupa aceleasi principiu ca si curbele 2D adica prin aproximarea curbei cu segmente de dreapta.

Pachetul grafic 3D care va fi dezvoltat in continuare apare ca un nivel superior al pachetului grafic 2D.

Clipping-ul obiectelor 3D se va realiza prin proiectarea obiectelor in planul ecranului iar apoi prin utilizarea procedurii de clipping 2D. Toate functiile 2D puse la dispozitie de pachetul grafic 2D vor putea fi referite, operand in cadrul planului de proiectie (plan de vedere).

B. Implementare

In cadrul acestei lucrari se vor realiza procedurile si functiile necesare pentru realizarea operatiilor:

  • proiectia ortografica
  • proiectia perspectiva
  • trasarea segmentelor de dreapta in coordonate 3d

Aceste rutine fac obiectul unitatii G3D_VIZUAL.

/*======================================================================*/
/* G3Dvizual.h                                                          */
/*======================================================================*/

/* coordonatele unui punct in spatiul 3D */
typedef struct _punct_3D
{
  double x;
  double y;
  double z;
} punct_3D;

/* lista de puncte in spatiul 3D */
typedef struct _lista_puncte3D
{
  int n;
  punct_3D puncte[50];
} lista_puncte3D;

/* tipurile de proiectii posibile */
typedef enum _tp {ortogr, perspect, caval, cabin} tip_proiectie;


/*
 * Stabileste utilizarea proiectiei ortografice 
 */
extern void ortografic(void);

/*
 * Stabileste utilizarea proiectiei perspectiva
 */
extern void perspectiva(void);

/*
 * Pozitioneaza centrul proiectiei perpective in
 * punctul de coordonate (0,0,-d)
 */
extern void centru_pr(double d);

/*
 * determina proiectia P'(sx,sy) a punctului (x,y,z) conform cu 
 * tipul proiectiei stabilite prin functiile ortografic sau perspectiva
 */
extern void proiecteaza (double x, double y, double z, double* sx, double* sy);


/*
 * Traseaza segmentul de dreapta determinat de punctele P1(x1,y1,z1)
 * si P2(x2,y2,z2)
 */
extern void linie_3d (punct_3D p1, punct_3D p2);


/*
 * Reprezinta punctul de coordonate P(x,y,z)
 */
extern void rpunct_3d (punct_3D p);


/*
 * Traseaza poligonul ale carui varfuri sunt precizate in variabila lista
 */
extern void poligon_3d(lista_puncte3D lista);

/*======================================================================*/
/* End of G3Dvizual.h                                                   */
/*======================================================================*/


/*======================================================================*/
/* G3Dvizual.c                                                          */
/*======================================================================*/
#include <stdio.h>
#include <math.h>

#include "G2Dnucleu.h"
#include "G2Dprimitive.h"
#include "G3Dvizual.h"

/* Structuri private --------------------------------------------------- */

/* Tipul proiectiei curente setat prin fct. ortografic sau perspectiva */
static tip_proiectie tip_curent_proiectie = perspect;

/* Centrul proiectiei perspectiva */
static double centru = 10.0;

/* Rutine publice ------------------------------------------------------- */

/*
 * Stabileste utilizarea proiectiei ortografice 
 */
void ortografic()
{
  tip_curent_proiectie = ortogr;
}

/*
 * Stabileste utilizarea proiectiei perspectiva
 */
void perspectiva()
{
  tip_curent_proiectie = perspect;
}

/*
 * Pozitioneaza centrul proiectiei perpective in
 * punctul de coordonate (0,0,-d)
 */
void centru_pr(double d)
{
  centru = d;
}

/*
 * determina proiectia P'(sx,sy) a punctului (x,y,z) conform cu 
 * tipul proiectiei stabilite prin functiile ortografic sau perspectiva
 */
void proiecteaza (double x, double y, double z, double* sx, double* sy)
{
  if (tip_curent_proiectie == perspect )
  {
    /* proiectia perspectiva */
    *sx = x*centru/(z+centru);
    *sy = y*centru/(z+centru);
  }
  else
  {
    *sx = x;
    *sy = y;
  }
} /* proiecteaza */ 

/*
 * Traseaza segmentul de dreapta determinat de punctele P1(x1,y1,z1)
 * si P2(x2,y2,z2)
 */
void linie_3d (punct_3D p1, punct_3D p2)
{
  double xp1,xp2,yp1,yp2;

  proiecteaza(p1.x, p1.y, p1.z, &xp1, &yp1);
  proiecteaza(p2.x, p2.y, p2.z, &xp2, &yp2);
  linie_2d(xp1, yp1, xp2, yp2);
}


/*
 * Reprezinta punctul de coordonate P(x,y,z)
 */
void rpunct_3d (punct_3D p)
{
  double xp,yp;

  proiecteaza(p.x, p.y, p.z, &xp, &yp);
  punct_2d(xp, yp);
}


/*
 * Traseaza poligonul ale carui varfuri sunt precizate in variabila lista
 */
void poligon_3d(lista_puncte3D lista)
{
  /* Definirea procedurii poligon_3d */
} 

/*======================================================================*/
/* End of G3Dvizual.c                                                   */
/*======================================================================*/

Download G3Dvizual.h, G3Dvizual.c.

C. Aplicatii

1. Realizati unitatea G3D_VIZUAL.

2. Realizati procedurile necesare pentru implementarea proiectiilor paralele cavaliera si cabinet.

3. Utilizand procedura linie_3d scrieti o procedura pentru trasarea curbelor parametrice 3d.

4. Testati procedurile realizate reprezentand un cub cu latura de 10 unitati. Cubul se va desena prin reprezentarea muchiilor sale, consecutiv in proiectie ortografica si perspectiva. Se va modifica pozitia centrului de proiectie si se vor urmari efectele proiectiei perspective.

5. Vizualizati in proiectie perspectiva un segment de dreapta 3d care are unul din capete la o cota -centru<Z<0 iar celalalt la cota Z<-centru. Observati imaginile obtinute.

6. Derivati ecuatiile proiectiei perspectiva considerand ca obiectul este in fata planului de proiectie, acesta fiind plasat la distanta f fata de originea O pe axa Oz>0. Vizualizati cubul de la punctul 4 in aceste conditii.

7. Elaborati o procedura care asigura operatia de clipping 3D in adancime fata de planele z=zmin, z=zmax si incorporati-o corespunzator in procedura linie_3d. Scrieti o procedura de interfata pentru definirea planelor z=zmin, z=zmax.

8. Elaborati un modul G3D_VECTOR care contine proceduri si functii pentru realizarea calculelor vectoriale. In fisierul de interfata (.h) se vor include:

typedef struct _vector
{
  double x, y, z;
} vector;

extern void set_vector (double a, double b, double c, vector* v);
extern void aduna_vectori (vector a, vector b, vector* c);
extern void scade_vectori (vector a, vector b, vector* c);
extern void produs_vectorial (vector a, vector b,vector* c);
extern void normalizeaza (vector* v);
extern double produs_scalar (vector a, vector b);
extern double cos_vectori (vector a,vector b);
extern double lungime_vector (vector v);

9. Elaborati un modul G3D_MATRICE care contine proceduri si functii pentru realizarea calculelor matriciale. In fisierul de interfata (.h) se vor defini:

typedef double MAT3D[4][4];

extern void nul (MAT3D m); /* creaza matricea nula */
extern void id_mat (MAT3D m); /* creaza matricea identitate */
extern void mult_mat (MAT3D matprod, MAT3D m);
/* inmulteste la dreapta matricea matprod cu m si retine
   matricea produs in matprod */

 

Home ][ Up ][ Previous ][ Next ]

Send mail to sorin@aspc.cs.utt.ro with questions or comments about this web site.
Copyright © 2000 Graphics Laboratory
Last modified: March 28, 2000