]> Dogcows Code - chaz/yoink/blobdiff - src/moof/plane.hh
the massive refactoring effort
[chaz/yoink] / src / moof / plane.hh
diff --git a/src/moof/plane.hh b/src/moof/plane.hh
new file mode 100644 (file)
index 0000000..3de87e4
--- /dev/null
@@ -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 <moof/math.hh>
+#include <moof/shape.hh>
+
+
+namespace moof {
+
+
+template <int D> class aabb;
+template <int D> 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_
+
This page took 0.01827 seconds and 4 git commands to generate.