/*] Copyright (c) 2009-2010, Charles McGarvey [************************** **] All rights reserved. * * vi:ts=4 sw=4 tw=75 * * Distributable under the terms and conditions of the 2-clause BSD license; * see the file COPYING for a complete text of the license. * **************************************************************************/ #ifndef _MOOF_PLANE_HH_ #define _MOOF_PLANE_HH_ #include #include namespace Mf { template class Aabb; template class Sphere; /* * A plane in 3-space defined by the equation Ax + By + Cz = D, where [A, * B, C] is normal to the plane. */ struct Plane : public Shape<3> { Vector3 normal; Scalar d; typedef enum { NEGATIVE = -1, INTERSECT = 0, POSITIVE = 1 } Halfspace; Plane() {} Plane(const Vector3& vector, Scalar scalar) : normal(vector), d(scalar) {} Plane(Scalar a, Scalar b, Scalar c, Scalar scalar) : normal(a, b, c), d(scalar) {} bool intersectRay(const Ray<3>& ray, Ray<3>::Contact& hit) { // solve: [(ray.point + t*ray.direction) dot normal] + d = 0 Scalar denom = cml::dot(ray.direction, normal); // check for parallel condition if (denom == SCALAR(0.0)) { if (isEqual(cml::dot(ray.point, normal), -d)) { // the ray lies on the plane hit.distance = SCALAR(0.0); hit.normal.set(0.0, 0.0, 0.0); return true; } // no solution return false; } Scalar numer = cml::dot(ray.point, normal) + d; hit.distance = -numer / denom; if (hit.distance < SCALAR(0.0)) return false; if (numer >= 0.0) hit.normal = normal; else hit.normal = -normal; return true; } /* Causes the normal of the plane to become normalized. The scalar may * also be changed to keep the equation true. Word to the wise: don't * normalize a plane if the normal is the zero vector. */ void normalize() { Scalar mag = normal.length(); normal /= mag; d /= mag; } /** * Determine the shortest distance between a point and the plane. */ Scalar getDistanceToPoint(const Vector3& point) const { return cml::dot(point, normal) + d; } Halfspace intersects(const Vector3& point) const { Scalar distance = getDistanceToPoint(point); if (isEqual(distance, 0.0)) return INTERSECT; else if (distance < 0.0) return NEGATIVE; else return POSITIVE; } Halfspace intersects(const Aabb<3>& aabb) const; Halfspace intersects(const Sphere<3>& sphere) const; }; } // namespace Mf #endif // _MOOF_PLANE_HH_