X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fmoof%2Fplane.hh;fp=src%2Fmoof%2Fplane.hh;h=3de87e4e3a8ac0bb5f41334321d2c04bfb98c980;hp=0000000000000000000000000000000000000000;hb=831f04d4bc19a390415ac0bbac4331c7a65509bc;hpb=299af4f2047e767e5d79501c26444473bda64c64 diff --git a/src/moof/plane.hh b/src/moof/plane.hh new file mode 100644 index 0000000..3de87e4 --- /dev/null +++ b/src/moof/plane.hh @@ -0,0 +1,124 @@ + +/*] 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_ + +/** + * \file plane.hh + * Classes and functions related to planes. + */ + +#include +#include + + +namespace moof { + + +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; + + enum halfspace + { + negative = -1, + intersecting = 0, + positive = 1 + }; + + 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 intersect_ray(const ray<3>& ray, ray<3>::contact& hit) + { + // solve: [(ray.point + t*ray.direction) dot normal] + d = 0 + + scalar denom = dot(ray.direction, normal); + + // check for parallel condition + if (denom == SCALAR(0.0)) + { + if (is_equal(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 = 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 distance_to_point(const vector3& point) const + { + return dot(point, normal) + d; + } + + halfspace intersects(const vector3& point) const + { + scalar distance = distance_to_point(point); + + if (is_equal(distance, 0.0)) return intersecting; + 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 moof + +#endif // _MOOF_PLANE_HH_ +