/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Octobre 2005 */ /* Classe de gestion de surfaces */ /* spheriques */ #include #include #include #include #include #include "ModuleFont.h" #include "Sphere.h" #include "Droite.h" #include "Rayon.h" Sphere::Sphere(void) { centre = new Position(); rayon = 1.0F; } Sphere::Sphere(float x,float y,float z,float r) { centre = new Position(x,y,z); rayon = r; } Sphere::Sphere(Position *p,float r) { centre = new Position(p); rayon = r; } Sphere::~Sphere(void) { delete(centre); } static float vmin(float a,float b) { return(( a < b ) ? a : b); } static float vmax(float a,float b) { return(( a > b ) ? a : b); } int Sphere::testIntersection(Droite *d) { float a = d->d->x*d->d->x+ d->d->y*d->d->y+ d->d->z*d->d->z; float b = 2*(d->d->x*(d->p->x-centre->x)+ d->d->y*(d->p->y-centre->y)+ d->d->z*(d->p->z-centre->z)); float c = (d->p->x-centre->x)*(d->p->x-centre->x)+ (d->p->y-centre->y)*(d->p->y-centre->y)+ (d->p->z-centre->z)*(d->p->z-centre->z)- rayon*rayon; float delta = b*b-4*a*c; if ( fabs(delta) < 0.0001F ) return(1); if ( delta < 0.0F ) return(0); return(2); } Position **Sphere::intersection(Droite *d) { float a = d->d->x*d->d->x+ d->d->y*d->d->y+ d->d->z*d->d->z; float b = 2*(d->d->x*(d->p->x-centre->x)+ d->d->y*(d->p->y-centre->y)+ d->d->z*(d->p->z-centre->z)); float c = (d->p->x-centre->x)*(d->p->x-centre->x)+ (d->p->y-centre->y)*(d->p->y-centre->y)+ (d->p->z-centre->z)*(d->p->z-centre->z)- rayon*rayon; float delta = b*b-4*a*c; if ( fabs(delta) < 0.0001F ) { float t = -b/(2.0F*a); Position **pts =(Position **) calloc(2,sizeof(Position *)); pts[0] = d->position(t); pts[1] = NULL; return(pts); } if ( delta < 0.0F ) return(NULL); float t1 = (-b-sqrt(delta))/(2.0F*a); float t2 = (-b+sqrt(delta))/(2.0F*a); Position **pts =(Position **) calloc(2,sizeof(Position *)); pts[0] = d->position(t1); pts[1] = d->position(t2); return(pts); } int Sphere::testIntersection(Rayon *r) { float b = 2*(r->d->x*(r->p->x-centre->x)+ r->d->y*(r->p->y-centre->y)+ r->d->z*(r->p->z-centre->z)); float c = (r->p->x-centre->x)*(r->p->x-centre->x)+ (r->p->y-centre->y)*(r->p->y-centre->y)+ (r->p->z-centre->z)*(r->p->z-centre->z)- rayon*rayon; float delta = b*b-4*c; if ( fabs(delta) < 0.0001F ) { float t = -b/2.0F; if ( t >= 0.0F ) return(1); return(0); } if ( delta < 0.0F ) return(0); float t1 = (-b-sqrt(delta))/2.0F; float t2 = (-b+sqrt(delta))/2.0F; if ( ( t1 < 0.0F ) && ( t2 < 0.0F ) ) return(0); if ( ( t1 >= 0.0F ) && ( t2 >= 0.0F ) ) return(2); return(1); } Position *Sphere::intersection(Rayon *r) { float b = 2*(r->d->x*(r->p->x-centre->x)+ r->d->y*(r->p->y-centre->y)+ r->d->z*(r->p->z-centre->z)); float c = (r->p->x-centre->x)*(r->p->x-centre->x)+ (r->p->y-centre->y)*(r->p->y-centre->y)+ (r->p->z-centre->z)*(r->p->z-centre->z)- rayon*rayon; float delta = b*b-4*c; if ( fabs(delta) < 0.0001F ) { float t = -b/2.0F; if ( t >= 0.0F ) return(r->position(t)); return(NULL); } if ( delta < 0.0F ) return(NULL); float t1 = (-b-sqrt(delta))/2.0F; float t2 = (-b+sqrt(delta))/2.0F; if ( ( t1 < 0.0F ) && ( t2 < 0.0F ) ) return(NULL); if ( ( t1 >= 0.0F ) && ( t2 >= 0.0F ) ) return(r->position(min(t1,t2))); return(r->position(max(t1,t2))); } void Sphere::dessine(void) { glPushMatrix(); glTranslatef(centre->x,centre->y,centre->z); glutSolidSphere(rayon,36,36); glPopMatrix(); } void Sphere::print(char *format) { simpleBitmapOutput(1,REGULAR8x13,format, centre->x,centre->y,centre->z,rayon); }