/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Avril 2001 */
/* Calculs sur l'energie diffusee */
/* par une surface */
#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 ;
}
int main(int argc,char **argv) {
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) ;
return(0);
}