]> Dogcows Code - chaz/yoink/blobdiff - src/Moof/Plane.hh
cade lab fixes
[chaz/yoink] / src / Moof / Plane.hh
index 797edc05c39fe13283c4a52088502fcb6e2f132c..b39891790f16a6afc682c9e753642cf8015ebd5e 100644 (file)
 
 #ifndef _MOOF_PLANE_HH_
 #define _MOOF_PLANE_HH_
-       
+
 #include <Moof/Math.hh>
+#include <Moof/Shape.hh>
 
 
 namespace Mf {
 
 
-class Plane
+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>
 {
-       Vector4 components;
+       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>::Intersection& 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;
+       }
 
-public:
+       Halfspace intersects(const Aabb<3>& aabb) const;
+       Halfspace intersects(const Sphere<3>& sphere) const;
 };
 
 
This page took 0.019646 seconds and 4 git commands to generate.