/* * CS5600 University of Utah * Charles McGarvey * mcgarvey@eng.utah.edu */ #ifndef _SPHERE_HH_ #define _SPHERE_HH_ #include "element.hh" namespace rt { /* * A class for a sphere object. */ class sphere : public element { vec_t origin; scal_t radius; public: sphere(vec_t o, scal_t r = S(1.0)) : origin(o), radius(r) {} virtual ~sphere() {} virtual bool intersect(ray_t ray, contact_t& hit) const { vec_t b = vec_sub(origin, ray.o); scal_t z = vec_dot(b, ray.d); // check if the sphere is behind the ray if (z < S(0.0)) { return false; } scal_t d2 = vec_dot(b, b) - z * z; scal_t r2 = radius * radius; // check for an intersection if (r2 < d2) { return false; } hit.d = z - std::sqrt(r2 - d2); if (hit.d < S(0.0)) { return false; } hit.p = ray_solve(ray, hit.d); hit.n = vec_sub(hit.p, origin); return true; } virtual vec_t txcoord(vec_t point) const { vec_t uv = VEC_ZERO; scal_t theta = scal_atan2(point.z, point.x); scal_t phi = asin(point.y / radius); uv.x = theta / (S(2.0) * M_PI) + S(0.5); uv.y = phi / M_PI + S(0.5); return uv; } }; /* * Destroy a new'd sphere, releasing its memory. */ INLINE_MAYBE void sphere_destroy(sphere* s) { delete s; } } // namespace rt #endif // _SPHERE_HH_