src/rcrt/primitives/Sphere.cpp

Go to the documentation of this file.
00001 #include "Sphere.h"
00002 #include <limits>
00003 #include <cmath>
00004 #include <iostream>
00005 
00006 using namespace std;
00007 
00008 namespace rcrt
00009 {
00010 
00011 
00012 Sphere::Sphere(const Point3D& c, float r, SolidObject* parent):Primitive(parent),center(c),radius(r)
00013 {
00014         box.extend(center+Vec3D(radius,radius,radius));
00015         box.extend(center-Vec3D(radius,radius,radius));
00016 }
00017 
00018 
00019 Sphere::Sphere(const Sphere& s, SolidObject* parent):Primitive(parent)
00020 {
00021         assign(s);
00022 }
00023 
00024 
00025 Sphere::~Sphere()
00026 {
00027 }
00028 
00029 
00030 void Sphere::assign(const Sphere& s)
00031 {
00032         center = s.center;
00033         radius = s.radius;
00034 }
00035 
00036 Intersection Sphere::intersect(Ray& ray) const
00037 {       
00038         Vec3D v = ray.org() - center;
00039         float b = -( v * ray.dir());
00040         float det = (b * b) - v * v  + radius * radius;
00041         if (det <= 0)
00042                 return Intersection();
00043         else {
00044                 det = sqrt( det );
00045                 float i1 = b - det;
00046                 float i2 = b + det;
00047                 if (i2 <= 0)
00048                         return Intersection();
00049                 else {
00050                         if (i1 < 0) 
00051                         {
00052                                 Point3D hitP(ray.atDistance(i2));
00053                                 Vec3D vec = (hitP-center).normalize();
00054                                 float theta = acos(vec.z());
00055                                 float phi = atan2(vec.y(),vec.x());
00056                                 if(phi < 0)
00057                                         phi += 2*M_PI;
00058                                 Intersection is(i2, this, hitP, theta, phi, true);
00059                                 is.setSNormalL(vec);
00060                             is.setGNormalL(vec);
00061                             return is;
00062                         }
00063                         else
00064                         {
00065                                 Point3D hitP(ray.atDistance(i1));
00066                                 Vec3D vec = (hitP-center).normalize();
00067                                 float theta = acos(vec.z());
00068                                 float phi = atan2(vec.y(),vec.x());
00069                                 if(phi < 0)
00070                                         phi += 2*M_PI;
00071                                 Intersection is(i1, this, hitP, theta, phi, false);
00072                                 is.setSNormalL(vec);
00073                             is.setGNormalL(vec);
00074                             return is;
00075                         }
00076                 }
00077         }
00078 }
00079 
00080 
00081 const AABB& Sphere::getBoundingBox() const
00082 {
00083         return box;
00084 }
00085 
00086 
00087 const Point3D& Sphere::getCentroid() const
00088 {
00089         return center;
00090 }
00091 
00092 float Sphere::getRadius() const
00093 {
00094         return radius;
00095 }
00096 
00097 Vec3D Sphere::getSNormal(float theta, float phi) const
00098 {
00099         return getGNormal(theta, phi);
00100 }
00101 
00102 Vec3D Sphere::getGNormal(float theta, float phi) const
00103 {
00104         Vec3D no(cos(phi) * sin(theta),
00105         sin(phi) * sin(theta),
00106         cos(theta));
00107         no.normalize();
00108         return no;
00109 }
00110 
00111 Point2D Sphere::getUV(float theta, float phi) const
00112 {
00113         return Point2D(phi/(2*M_PI), theta/M_PI);
00114 }
00115 
00116 AABB Sphere::clipBox(AABB& cbox) const {
00117         return getBoundingBox();
00118 }
00119 
00120 }

Generated on Thu Jan 31 19:26:19 2008 for RenderingCompetitionRayTracer by  doxygen 1.5.3