Solutions des exercices |
||
|
Mini-langage
pour OpenGL,
fonctions basiques pour Auxiliary library Caméras, implantation en VRML et en OpenGL Mise en route en VRML et en OpenGL Utilisation des primitives graphiques
Dernière modification |
Push Push T(1.5,0,-1.5) C Pop Push T(-1.5,0,-1.5) R(30,0,1,0) T(0,0,-0.5) C Pop Push T(-1.5,0,1.5) Z(1,1,2) C Pop Push T(1.5,0,1.5) R(45,0,1,0) C Pop Pop Push R(r1,0,1,0) T(1.5,0,0) Push Z(3,1,1) C Pop T(1.5,0,0) R(r2,0,1,0) T(1.5,0,0) Push Z(3,0.8,0.8) C Pop T(1.8,0,0) R(r3,1,0,0) Push Z(0.6,1.2,1.8) C Pop T(0.8,0,0) Push T(0,0,-0.2-d) Push Z(1.0,1.2,0.4) C Pop Pop Push T(0,0,0.2+d) Push Z(1.0,1.2,0.4) C Pop Pop Pop
L = Ip Kd cos(q) L = Ip Kd ( #include <stdio.h>
#include <math.h>
typedef struct coord_3D {
float x ;
float y ;
float z ; } coord_3D ;
typedef struct couleur {
float r ;
float v ;
float b ; } couleur ;
typedef struct direction_3D {
float dx ;
float dy ;
float dz ; } direction_3D ;
typedef struct pointLight {
coord_3D pos ;
couleur coul ;
float energie ; } pointLight ;
typedef struct materiau {
couleur diffusion ;
couleur reflexion ;
couleur transmission ;
couleur emission ; } materiau ;
typedef struct energie {
float er ;
float ev ;
float eb ; } energie ;
float distance(coord_3D *p1,
coord_3D *p2) {
double x = p1->x - p2->x ;
double y = p1->y - p2->y ;
double z = p1->z - p2->z ;
double d2 = x*x + y*y + z*z ;
return((float) pow(d2,0.5)) ;
}
void calculVecteurNorme(coord_3D *pi,
coord_3D *pf,
direction_3D *n) {
double x = pf->x - pi->x ;
double y = pf->y - pi->y ;
double z = pf->z - pi->z ;
double d2 = x*x + y*y + z*z ;
d2 = pow(d2,0.5) ;
n->dx =(float) (x / d2) ;
n->dy =(float) (y / d2) ;
n->dz =(float) (z / d2) ;
}
float produitScalaire(direction_3D *d1,
direction_3D *d2) {
return(d1->dx*d2->dx +
d1->dy*d2->dy +
d1->dz*d2->dz) ;
}
/* En entree les coordonnees du point p
et la pointlight l. En sortie l'energie
recue*/
void calculEnergieRecue(coord_3D *p,
pointLight *l,
energie *e) {
float d = distance(p,&l->pos) ;
float atten = 1.0F / d / d ;
e->er = atten * l->energie * l->coul.r ;
e->ev = atten * l->energie * l->coul.v ;
e->eb = atten * l->energie * l->coul.b ;
}
/* En entree les coordonnees du point p,
la normale n a la surface au point p, le
materiau m de la surface, la pointlight l.
En sortie l'energie diffusee*/
void calculEnergieDiffusee(coord_3D *p,
direction_3D *n,
materiau *m,
pointLight *l,
energie *e) {
energie recu ;
calculEnergieRecue(p,l,&recu) ;
direction_3D li ;
calculVecteurNorme(p,&l->pos,&li) ;
float scal = produitScalaire(&li,n) ;
if ( scal < 0.0F )
scal = 0.0F ;
e->er = recu.er * scal * m->diffusion.r ;
e->ev = recu.ev * scal * m->diffusion.v ;
e->eb = recu.eb * scal * m->diffusion.b ;
}
void main(void) {
coord_3D p = { 1.0F,2.0F,0.0F } ;
direction_3D n = { 0.0F,0.0F,1.0F } ;
pointLight l = { {-1.0F,2.0F,4.0F},
{1.0F,0.5F,0.5F},
5.0F } ;
materiau m = { {0.5F,0.5F,1.0F},
{0.0F,0.0F,0.0F},
{0.0F,0.0F,0.0F},
{0.0F,0.0F,0.0F} } ;
energie e ;
energie ed ;
calculEnergieRecue(&p,&l,&e) ;
printf("Energie recue : %f %f %f\n",
e.er,e.ev,e.eb) ;
calculEnergieDiffusee(&p,&n,&m,&l,&ed) ;
printf("Energie diffusee : %f %f %f\n",
ed.er,ed.ev,ed.eb) ;
}
Fichier source: TD-Diffusion.cpp
#include <stdio.h>
#include <math.h>
typedef struct coord_3D {
float x ;
float y ;
float z ; } coord_3D ;
typedef struct direction_3D {
float dx ;
float dy ;
float dz ; } direction_3D ;
typedef struct rayon {
coord_3D pos ;
direction_3D dir ; } rayon ;
/* En entree le rayon r teste. En sortie
le nombre d'intersection(s) */
int intersectionSphere(rayon *r) {
float a = r->dir.dx*r->dir.dx +
r->dir.dy*r->dir.dy +
r->dir.dz*r->dir.dz ;
float b = 2*(r->dir.dx*r->pos.x +
r->dir.dy*r->pos.y +
r->dir.dz*r->pos.z) ;
float c = r->pos.x*r->pos.x +
r->pos.y*r->pos.y +
r->pos.z*r->pos.z - 1 ;
float delta = b*b - 4*a*c ;
if ( delta > 0 )
return(2) ;
if ( delta == 0 )
return(1) ;
return(0) ;
}
int posIntersectionSphere(rayon *r,
coord_3D *p) {
float a = r->dir.dx*r->dir.dx +
r->dir.dy*r->dir.dy +
r->dir.dz*r->dir.dz ;
float b = 2*(r->dir.dx*r->pos.x +
r->dir.dy*r->pos.y +
r->dir.dz*r->pos.z) ;
float c = r->pos.x*r->pos.x +
r->pos.y*r->pos.y +
r->pos.z*r->pos.z - 1 ;
float delta = b*b - 4*a*c ;
if ( delta > 0 ) {
float rcn =(float) pow(delta,0.5) ;
float d = (-b-rcn)/2/a ;
if ( d > 0 ) {
p->x = r->pos.x + d * r->dir.dx ;
p->y = r->pos.y + d * r->dir.dy ;
p->z = r->pos.z + d * r->dir.dz ;
return(1) ; }
else {
float d = (-b+rcn)/2/a ;
if ( d > 0 ) {
p->x = r->pos.x + d * r->dir.dx ;
p->y = r->pos.y + d * r->dir.dy ;
p->z = r->pos.z + d * r->dir.dz ;
return(1) ; } }
return(0) ; }
if ( delta == 0 ) {
float d = -b/2/a ;
p->x = r->pos.x + d * r->dir.dx ;
p->y = r->pos.y + d * r->dir.dy ;
p->z = r->pos.z + d * r->dir.dz ;
return(1) ; }
return(0) ;
}
float produitScalaire(direction_3D *d1,
direction_3D *d2) {
return(d1->dx*d2->dx +
d1->dy*d2->dy +
d1->dz*d2->dz) ;
}
void calculReflexion(rayon *r,
float d,
rayon *ref) {
ref->pos.x = r->pos.x + d * r->dir.dx ;
ref->pos.y = r->pos.y + d * r->dir.dy ;
ref->pos.z = r->pos.z + d * r->dir.dz ;
direction_3D n = { ref->pos.x,
ref->pos.y,
ref->pos.z } ;
direction_3D i = { -r->dir.dx,
-r->dir.dy,
-r->dir.dz } ;
float scal = produitScalaire(&n,&i) ;
ref->dir.dx = 2 * n.dx * scal - i.dx ;
ref->dir.dy = 2 * n.dy * scal - i.dy ;
ref->dir.dz = 2 * n.dz * scal - i.dz ;
}
/* En entree le rayon r teste. En sortie
un booleen indiquant l'existence d'un
rayon reflechi, le rayon reflechi ref */
int rayonReflechiSphere(rayon *r,
rayon *ref) {
float a = r->dir.dx*r->dir.dx +
r->dir.dy*r->dir.dy +
r->dir.dz*r->dir.dz ;
float b = 2*(r->dir.dx*r->pos.x +
r->dir.dy*r->pos.y +
r->dir.dz*r->pos.z) ;
float c = r->pos.x*r->pos.x +
r->pos.y*r->pos.y +
r->pos.z*r->pos.z - 1 ;
float delta = b*b - 4*a*c ;
a *= 2 ;
if ( delta > 0 ) {
float rcn =(float) pow(delta,0.5) ;
float d = (-b-rcn)/a ;
if ( d > 0 ) {
calculReflexion(r,d,ref) ;
return(1) ; }
else {
float d = (-b+rcn)/2 ;
if ( d > 0 ) {
calculReflexion(r,d,ref) ;
return(1) ; } }
return(0) ; }
if ( delta == 0 ) {
float d = -b/a ;
calculReflexion(r,d,ref) ;
return(1) ; }
return(0) ;
}
void main(void) {
/* rayon r = { {3.0F,-0.2F,-0.3F},
{-0.95F,0.22F,0.22F} } ;*/
/* rayon r = { {3.0F,0.7071067811F,
0.7071067811F},
{-1.0F,0.0F,0.0F} } ;*/
/* rayon r = { {3.0F,0.7071067811F,0.0F},
{-1.0F,0.0F,0.0F} } ;*/
rayon r = { {3.0F,0.0F,0.7071067811F},
{-1.0F,0.0F,0.0F} } ;
printf("Rayon initial : %f %f %f\n",
r.pos.x,r.pos.y,r.pos.z) ;
printf(" %f %f %f\n",
r.dir.dx,r.dir.dy,r.dir.dz) ;
int n = intersectionSphere(&r) ;
printf("Nombre intersections : %d\n",n) ;
coord_3D p ;
int inter = posIntersectionSphere(&r,&p) ;
if ( inter ) {
printf("Pos intersection : %f %f %f\n",
p.x,p.y,p.z) ; }
else {
printf("Pas d'intersection\n") ; }
rayon ref ;
inter = rayonReflechiSphere(&r,&ref) ;
if ( inter ) {
printf("Rayon reflechi : %f %f %f\n",
ref.pos.x,ref.pos.y,ref.pos.z) ;
printf(" %f %f %f\n",
ref.dir.dx,
ref.dir.dy,
ref.dir.dz) ; }
else {
printf("Pas de reflexion\n") ; }
}
Fichier source: TD-Reflexion.cpp
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct coord_3D {
float x ;
float y ;
float z ; } coord_3D ;
typedef struct polygone {
int n ;
coord_3D *c ; } polygone ;
void pixel(float x,float y,float z) {
printf("%f %f %f\n",x,y,z) ;
}
double power(double v,int p) {
return(( !v && !p ) ?
1.:
pow(v,(double) p)) ;
}
/* En entree le polygone p, le nombre
de points n */
void bezier(polygone *p,int n) {
int i,j ;
float t,mt ;
float *cn,x,y,z,fac ;
cn =(float *) calloc(p->n,sizeof(float));
cn[0] = 1 ;
cn[1] =(float) (p->n-1) ;
for ( i = 2 ; i < p->n ; i++ )
cn[i] = cn[i-1] * (p->n - i) / i ;
for ( i = 0 ; i < n ; i++ ) {
t =(float) i/(n-1) ;
mt = 1-t ;
x = y = z = 0.0F ;
for ( j = 0 ; j < p->n ; j++ ) {
fac = cn[j]*(float) power(t,j)*
(float) power(mt,p->n-1-j);
x += fac * p->c[j].x ;
y += fac * p->c[j].y ;
z += fac * p->c[j].z ; }
pixel(x,y,z) ; }
free(cn) ;
}
void main(void) {
coord_3D c[8] = { {-6.0F,-6.0F, 3.0F},
{-6.0F,-1.0F, 1.0F},
{-5.0F, 2.0F,-1.0F},
{-1.0F, 3.0F, 1.0F},
{ 2.0F, 1.0F, 4.0F},
{ 4.0F, 2.0F, 2.0F},
{ 5.0F, 5.0F,-2.0F},
{ 6.0F, 6.0F,-4.0F} } ;
polygone p = { 8,c } ;
bezier(&p,50) ;
}
Fichier source: TD-Bezier.cpp static GLfloat pts[7][3] = { {3,2,-1},{-4,5,-4}, {-5,4,3},{-1,-3,-2}, {4,-1,0}}; void traceBezierGL(void) { glMap1f(GL_MAP1_VERTEX_3, 0.0,1.0,3,5,&pts[0][0]); glEnable(GL_MAP1_VERTEX_3); glColor3f(0.0,1.0,1.0); glBegin(GL_POINTS); for ( int i = 0 ; i <= 100 ; i++ ) glEvalCoord1f((GLfloat) i/100.0F); glEnd(); } Fichier source complet: TD-Bezier-GL.cpp
float p = 0.55 ;
float pts1[4][3] = { {1.0F,0.0F,0.0F},
{1.0F,p,0.0F},
{p,1.0F,0.0F},
{0.0F,1.0F,0.0F} } ;
void traceQuartCercleBezierGL(float r) {
glPushMatrix() ;
glScalef(r,r,r) ;
glMap1f(GL_MAP1_VERTEX_3,
0.0,1.0,3,4,&pts1[0][0]);
glEnable(GL_MAP1_VERTEX_3);
glColor3f(0.0,1.0,1.0);
glBegin(GL_POINTS);
for ( int i = 0 ; i <= n ; i++ )
glEvalCoord1f((GLfloat) i/100.0F);
glEnd();
glPopMatrix() ;
}
void traceCercleBezierGL(float r) {
glPushMatrix() ;
traceQuartCercleBezierGL(r) ;
glRotatef(90.0F,0.0F,0.0F,1.0F) ;
traceQuartCercleBezierGL(r) ;
glRotatef(90.0F,0.0F,0.0F,1.0F) ;
traceQuartCercleBezierGL(r) ;
glRotatef(90.0F,0.0F,0.0F,1.0F) ;
traceQuartCercleBezierGL(r) ;
glPopMatrix() ;
}
Fichier source complet: TD-Bezier-GL-Cercle.cpp
float p = 0.55F ;
float pts1[16][3] = { {1.0F,0.0F,1.0F},
{1.0F,p,1.0F},
{p,1.0F,1.0F},
{0.0F,1.0F,1.0F},
{1.0F,0.0F,0.3F},
{1.0F,p,0.3F},
{p,1.0F,0.3F},
{0.0F,1.0F,0.3F},
{1.0F,0.0F,-0.3F},
{1.0F,p,-0.3F},
{p,1.0F,-0.3F},
{0.0F,1.0F,-0.3F},
{1.0F,0.0F,-1.0F},
{1.0F,p,-1.0F},
{p,1.0F,-1.0F},
{0.0F,1.0F,-1.0F} } ;
void traceQuartTuyauBezierGL(float r,
float h) {
glPushMatrix() ;
glScalef(r,r,h/2) ;
glMap2f(GL_MAP2_VERTEX_3,0.0F,1.0F,
3,4,
0.0F,1.0F,
12,4,
(float *) pts1);
glEnable(GL_MAP2_VERTEX_3);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glMapGrid2f(np1,0.0,1.0,np2,0.0,1.0);
if ( ff )
glEvalMesh2(GL_LINE,0,np1,0,np2);
else
glEvalMesh2(GL_FILL,0,np1,0,np2);
glPopMatrix() ;
}
void traceTuyauBezierGL(float r,float h) {
glPushMatrix() ;
traceQuartTuyauBezierGL(r,h) ;
glRotatef(90.0F,0.0F,0.0F,1.0F) ;
traceQuartTuyauBezierGL(r,h) ;
glRotatef(90.0F,0.0F,0.0F,1.0F) ;
traceQuartTuyauBezierGL(r,h) ;
glRotatef(90.0F,0.0F,0.0F,1.0F) ;
traceQuartTuyauBezierGL(r,h) ;
glPopMatrix() ;
}
Fichier source complet: TD-Bezier-GL-Tuyau.cpp Fichier source complet: TD-Bezier-GL-Tuyau2.cpp
float p = 0.55F ;
float pts1[10][2] = { {0.0F,-5.0F},
{5.0F,-5.0},
{4.5F,-4.0F},
{2.0F,-2.0F},
{1.5F,0.0F},
{0.2F,1.0F},
{0.2F,2.0F},
{1.5F,4.0F},
{1.5F,5.0F},
{0.5F,5.0F} } ;
void points(float *pts) {
glDisable(GL_LIGHTING) ;
glPointSize(5.0);
glColor3f(0.0,1.0,1.0);
glBegin(GL_POINTS);
for ( int i = 0 ; i < 40 ; i++ )
glVertex3fv(&pts[i*3]);
glEnd();
glEnable(GL_LIGHTING) ;
}
void traceQuartVaseBezierGL(void) {
glPushMatrix() ;
float pts[10][4][3] ;
for ( int i = 0 ; i < 10 ; i++ ) {
pts[i][0][0] = pts1[i][0] ;
pts[i][0][1] = pts1[i][1] ;
pts[i][0][2] = 0.0F ;
pts[i][1][0] = pts1[i][0] ;
pts[i][1][1] = pts1[i][1] ;
pts[i][1][2] = p*pts1[i][0] ;
pts[i][2][0] = p*pts1[i][0] ;
pts[i][2][1] = pts1[i][1] ;
pts[i][2][2] = pts1[i][0] ;
pts[i][3][0] = 0.0F ;
pts[i][3][1] = pts1[i][1] ;
pts[i][3][2] = pts1[i][0] ; }
glMap2f(GL_MAP2_VERTEX_3,
0.0F,1.0F,
3,4,
0.0F,1.0F,
12,10,
(float *) pts);
glEnable(GL_MAP2_VERTEX_3);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glMapGrid2f(np1,0.0,1.0,np2,0.0,1.0);
if ( ff )
glEvalMesh2(GL_LINE,0,np1,0,np2);
else
glEvalMesh2(GL_FILL,0,np1,0,np2);
glPopMatrix() ;
}
void traceVaseBezierGL(void) {
glPushMatrix() ;
traceQuartVaseBezierGL() ;
glRotatef(90.0F,0.0F,1.0F,0.0F) ;
traceQuartVaseBezierGL() ;
glRotatef(90.0F,0.0F,1.0F,0.0F) ;
traceQuartVaseBezierGL() ;
glRotatef(90.0F,0.0F,1.0F,0.0F) ;
traceQuartVaseBezierGL() ;
glPopMatrix() ;
}
Fichier source complet: TD-Bezier-GL-Revolution.cpp
|