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 }