Sunteți pe pagina 1din 7

Laborator 5 - SPG

Generarea i redarea suprafeelor B-spline


Reprezentarea parametric a curbelor B-spline este extins la reprezentarea peticelor de suprafee parametrice. De exemplu, considernd curbe B-spline cubice, un petic de suprafa bicubic B-spline este definit prin ecuaia:

Q(u,v) = Pij Bij (u,v) ,


i =0 j =0

(1)

n care Bij ( x ) este o funcie de baz de dou variabile u i v , care poate fi:

Bij (u,v ) = Bi,4 (u ) B j,4 ( v ) .

(2)

Suprafee complexe se obin din mai multe segmente de petice alturate, prin extinderea poliedrului caracteristic i a tabloului nodurilor.

Aplicaia 1. Redai o suprafa B-spline bicubic afind doar punctele de pe suprafa obtinute prin evaluarea parametrilor u i v. Indicaii: Programul care realizeaz aceast cerin poate fi construit pe baza indicaiilor corespunztoare Aplicaiei 1 din Laboratorul 4 n care funciile de amestec se calculeaz de aceast dat recursiv, conform relaiilor Cox De Boor:

1 Bi ,1 (u) = 0

pentru ui u ui +1

n rest u ui u u Bi,k (u) = Bi,k 1 (u) + i +k Bi +1,k 1 (u) . ui +k 1 ui ui +k ui +1

(3) (4)

unde k este ordinul curbei i Bi , k (u ) sunt funcii de amestec B-spline de grad k 1 i ordin de continuitate k 2 . Folosind valorile nodale
float knots_u[] = {0,0,0,0,1,1,1,1}; float knots_v[] = {0,0,0,0,1,1,1,1};

Laborator 5 - SPG

aplicaia va genera suprafaa Bezier din Aplicaia 1 - Laboratorul 4.


//nr. noduri unsigned int num_knots_u=8; unsigned int num_knots_v=8; //nr. puncte de control unsigned int num_cvs_u=4; unsigned int num_cvs_v=4; //gradul curbelor unsigned int degree_u=3; unsigned int degree_v=3; //ordinul curbelor unsigned int order_u=degree_u+1; unsigned int order_v=degree_v+1; float MinU() return } float MinV() return } float MaxU() return } float MaxV() return } { knots_u[degree_u]; { knots_v[degree_v]; { knots_v[num_knots_u-degree_u]; { knots_v[num_knots_v-degree_v];

float CoxDeBoor(float u,int i,int k,const float* Knots) { if(k==1) { if( Knots[i] <= u && u <= Knots[i+1] ) { return ...; } return ...; } float Den1 = Knots[i+k-1] - Knots[i]; float Den2 = Knots[i+k] - Knots[i+1]; float Eq1=0,Eq2=0; if(Den1>0) Eq1 = ... if(Den2>0) Eq2 = ... return Eq1+Eq2; } Point CalculateU(float t,int row) { // punctul final Point p; // sumarea efectelor punctelor si a functiilor de amestec // corespunzatoare for(unsigned int i=0;i!=num_cvs_u;++i) {

Laborator 5 - SPG

float Val = CoxDeBoor(t,i,order_u,knots_u); if(Val>0.001f) { // sumeaza efectul acestui punct de control asupra // acestei sectiuni de curba p.x += Val * Points[row][i].x; p.y += ...; p.z += ...; } } return p; } Point CalculateV(float t,int row) { ... } Point Calculate(float u,float v) { // Trebuie evaluate cele num_cvs_v curbe in directia u, iar // punctele corespunzatoare parametrului u transmis // sunt stocate in acest vector temporar si vor forma // cele num_cvs_v puncte de control pt curba din directia v. Point* temp = new Point[num_cvs_v]; // calculeaza fiecare din cele num_cvs_v puncte de pe curba // finala in directia v for(unsigned int i=0;i!=num_cvs_v;++i) temp[i] = CalculateU(u,i); // // // // date fiind cele num_cvs_v puncte, acestea pot fi folosite pentru evaluarea curbei bezier in directia v, iar punctul de pe aceasta curba este evaluat pt. parametrul v transmis.

// Acesta reprezinta punctul final de pe suprafata // corespunzator perechii (u,v). Point p = CalculateV(v,temp); delete [] temp; return p; } void Display() { glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glLoadIdentity(); gluLookAt( 5,16,20, 0,0,0, 0,1,0); // eye pos aim point up direction glColor3f(1,0,1); glPointSize(2); glBegin(GL_POINTS);

Laborator 5 - SPG

for(int i=0;i!=LOD;++i) { // calculeaza valoarea parametrului u float u = (MaxU()-MinU())*(float)i/(LOD-1) + MinU(); for(int j=0;j!=LOD;++j) { // calculeaza valoarea parametrului v float v = (MaxV()-MinV())*(float)j/(LOD-1) + MinV(); // evalueaza punctul corespnzator de pe suprafata Point p = Calculate(u,v); // deseneaza punctul glVertex3f(p.x,p.y,p.z); } } glEnd(); glutSwapBuffers(); }

Aplicaia 2. Generai o suprafa B-spline iluminat de o surs de lumin, folosind funciile puse la dispoziie de biblioteca de funcii utilitare GLU. Indicaii: Biblioteca OpenGL mpreun cu biblioteca de functii utilitare GLU, permit generarea i redarea suprafeelor B-spline n forma cea mai general, i anume B-spline neuniforme raionale (NURBS Non-Uniform Rational B-Spline). Prin alegerea parametrului de pondere w = 1 ( w fiind a patra coordonat n spaiul omogen tridimensional) pentru toate punctele de control, formele B-spline raionale au aceleai proprieti cu formele B-spline neraionale. Din acestea se pot defini forme B-spline uniforme sau neuniforme n funcie de intervalul parametric al nodurilor. Funciile de evaluare (evaluatori) glEvalCoord#() sunt primitive OpenGL care permit evaluarea punctelor de pe suprafee parametrice depinznd de modul de definire a evalurii. Evaluatorii pot fi implementai eficient n hardware. Pentru reprezentarea suprafeelor B-spline neuniforme raionale sunt necesare funcii mai complexe care utilizeaz evaluatori OpenGL. Aceste funcii sunt prevzute n biblioteca auxiliar GLU. O suprafa NURBS se definete ca un obiect de tipul GLUnurbsObj care se aloc n memoria liber (heap). Pentru un astfel de obiect se specific parametrii de definiie: punctele de control i vectorul de noduri (pentru cei doi parametrii). Pentru redarea imaginii unei suprafee NURBS se mai specific datele de eantionare, care definesc intervale la care se evalueaz punctele obiectului i aceste puncte sunt grupate n primitive geometrice (poligoane). (vezi Lucrarea de laborator nr. 3). Generarea i redarea suprafeei va fi realizat de funcia gluNurbsSurface(), creia i se transmit ca argumente tabloul de puncte de control (ctlpoints), vectorii de noduri (knots) i tipul evaluatorului (GL_MAP2_VERTEX3). Tabloul de puncte de control este generat de funcia init_surface().

Laborator 5 - SPG

Modul de redare a feelor poligoniale prin care se aproximeaz peticul de suprafa este stabilit prin funcia gluNurbsProperty() cu tipul de redare GLU_OUTLINE_POLYGON pentru wireframe respective GLU_FILL pentru redarea plin a feelor. Programul care realizeaz aceast cerin poate fi construit pe baza urmtoarelor funcii.
GLfloat ctlpoints[4][4][3]; int showPoints = 0; GLUnurbsObj *theNurb; void init_surface(void) { int u, v; for (u = 0; u < 4; u++) { for (v = 0; v < 4; v++) { ctlpoints[u][v][0] = 2.0*((GLfloat)u - 1.5); ctlpoints[u][v][1] = 2.0*((GLfloat)v - 1.5); if ( (u == 1 || u == 2) && (v == 1 || v == 2)) ctlpoints[u][v][2] = 3.0; else ctlpoints[u][v][2] = -3.0; } } } void init(void) { GLfloat mat_diffuse[] = { 0.7, 0.7, 0.0, 1.0 }; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shininess[] = { 110.0 }; glClearColor (1.0, 1.0, 1.0, 1.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); ... init_surface(); theNurb = gluNewNurbsRenderer(); gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 30); // gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON); gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL); } void display(void) { GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}; int i, j; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1, 0, 0); glPushMatrix(); glRotatef(340.0, 1.,0.,0.);

Laborator 5 - SPG

glScalef (0.5, 0.5, 0.5); gluBeginSurface(...); gluNurbsSurface(...); gluEndSurface(...); if (showPoints) { glPointSize(5.0); glDisable(GL_LIGHTING); glColor3f(1.0, 0.0, 0.0); glBegin(GL_POINTS); for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { glVertex3f(...); } } glEnd(); glEnable(GL_LIGHTING); } glPopMatrix(); glutSwapBuffers(); glFlush(); }

Imaginea creat la execuia aplicaiei este dat n figura urmatoare.

a)

b)

Fig. 1 Suprafa NURBS. a) wireframe; b) cu fee iluminate

Probleme propuse 1. S se aplice o textur pe suprafaa NURBS din exemplul anterior. Textura se va prelua dintr-un fiier. Apoi se vor vizualiza punctele de control i poliedrul caracteristic.

Laborator 5 - SPG

2. S se roteasc suprafaa NURBS dup oricare din cele trei axe de coordonate (la apsarea unor taste). Se va considera cazul n care sursa de lumin este rotit mpreun cu obiectul.