/* * CS5600 University of Utah * Charles McGarvey * mcgarvey@eng.utah.edu */ #ifndef _PLANE_HH_ #define _PLANE_HH_ #include "color.hh" #include "element.hh" namespace rt { /* * A class for a plane object. */ class plane : public element { public: color_t material; vec_t normal; scal_t distance; plane(vec_t n, scal_t d, color_t color = COLOR_WHITE) : normal(n), distance(d), material(color) {} plane(vec_t p, vec_t n, color_t color = COLOR_WHITE) : normal(vec_normalize(n)), distance(-vec_dot(normal, p)), material(color) {} plane(vec_t a, vec_t b, vec_t c, color_t color = COLOR_WHITE) : normal(vec_normalize(vec_cross(vec_sub(b, a), vec_sub(c, a)))), distance(-vec_dot(normal, a)), material(color) {} virtual ~plane() {} virtual bool intersect(ray_t ray, contact_t& hit) const { // solve: [(ray.point + t*ray.direction) dot normal] + d = 0 scal_t denom = vec_dot(ray.d, normal); // check for parallel condition if (denom == S(0.0)) { if (scal_isequal(vec_dot(ray.o, normal), -distance)) { hit.p = ray.o; hit.d = S(0.0); hit.n = VEC_ZERO; return true; // the ray lies on the plane } return false; // no solution } scal_t numer = vec_dot(ray.o, normal) + distance; hit.d = -numer / denom; if (hit.d < S(0.0)) { return false; } hit.p = ray_solve(ray, hit.d); if (S(0.0) <= numer) { hit.n = normal; } else { hit.n = vec_neg(normal); } return true; } virtual color_t color(vec_t point) const { return material; } }; /* * Destroy a new'd plane, releasing its memory. */ INLINE_MAYBE void plane_destroy(plane* p) { delete p; } } // namespace rt #endif // _PLANE_HH_