00001
00002
00003
00004 #include "geometry/Sphere.h"
00005
00006 inline static double sqr(double x){return x*x;}
00007 #include <cfloat>
00008
00009 Sphere::Sphere( const Point& origin, double radius)
00010 : Surface(origin, Vector(0,0,0) )
00011 , _radius(radius)
00012 {}
00013
00014
00015 void Sphere::printOn( std::ostream& ) const
00016 {
00017 }
00018
00019 double
00020 Sphere::how_near( const Point& x ) const
00021 {
00022
00023
00024 Vector r = x - origin();
00025 double rabs = r.mag();
00026
00027 return radius()>0? radius()-rabs : rabs+radius() ;
00028 }
00029
00030
00031 Vector
00032 Sphere::normal( const Point& x )const
00033 {
00034
00035
00036
00037 if(radius()>0 ) return (x - origin()).unit() ;
00038 else return (origin() - x).unit() ;
00039 }
00040 double
00041 Sphere::distance(const Point& x, const Vector& v, int inout)const
00042 {
00043
00044 Vector r = x-origin();
00045 double b = r*v,
00046 c= r.mag2()-sqr(radius()),
00047 disc = b*b-c,
00048 s;
00049
00050
00051
00052 if( disc<=0 ) return FLT_MAX;
00053 if( radius()<0 ) inout *=-1;
00054 int leaving = inout==1;
00055 if( b<0 )
00056 { s = (leaving) ? -b+sqrt(disc) :
00057 c/(-b+sqrt(disc));
00058 }
00059 else
00060 { s = (leaving) ? c/(-b-sqrt(disc)) : FLT_MAX;
00061 }
00062 return s>0? s : FLT_MAX;
00063
00064 }
00065