00001 00005 #include "Sphere.h" 00006 #include "BoundingBox.h" 00007 #include "HitRecord.h" 00008 #include "Point.h" 00009 #include "Ray.h" 00010 #include "Vector.h" 00011 #include <math.h> 00012 00013 Sphere::Sphere(Material* material, const Point& center, double radius) 00014 : Primitive(material), center(center), radius(radius) 00015 { 00016 inv_radius = 1./radius; 00017 } 00018 00019 Sphere::~Sphere() 00020 { 00021 } 00022 00023 void Sphere::getBounds(BoundingBox& bbox) const 00024 { 00025 Vector diag(radius, radius, radius); 00026 bbox.extend(center+diag); 00027 bbox.extend(center-diag); 00028 } 00029 00030 void Sphere::intersect(HitRecord& hit, const RenderContext&, const Ray& ray) const 00031 { 00032 Vector O(ray.origin()-center); 00033 const Vector& V(ray.direction()); 00034 double b = Dot(O, V); 00035 double c = Dot(O, O)-radius*radius; 00036 double disc = b*b-c; 00037 if(disc > 0){ 00038 double sdisc = sqrt(disc); 00039 double root1 = (-b - sdisc); 00040 if(!hit.hit(root1, this, matl)){ 00041 double root2 = (-b + sdisc); 00042 hit.hit(root2, this, matl); 00043 } 00044 } 00045 } 00046 00047 void Sphere::normal(Vector& normal, const RenderContext&, const Point& hitpos, 00048 const Ray& ray, const HitRecord& hit) const 00049 { 00050 normal = (hitpos-center)*inv_radius; 00051 }