]> Dogcows Code - chaz/yoink/blob - src/moof/plane.hh
83b5517385380a18f59c5cc167640d96b76e8e88
[chaz/yoink] / src / moof / plane.hh
1
2 /*] Copyright (c) 2009-2011, Charles McGarvey [*****************************
3 **] All rights reserved.
4 *
5 * Distributable under the terms and conditions of the 2-clause BSD license;
6 * see the file COPYING for a complete text of the license.
7 *
8 *****************************************************************************/
9
10 #ifndef _MOOF_PLANE_HH_
11 #define _MOOF_PLANE_HH_
12
13 /**
14 * \file plane.hh
15 * Classes and functions related to planes.
16 */
17
18 #include <moof/math.hh>
19 #include <moof/shape.hh>
20
21
22 namespace moof {
23
24
25 // forward declarations
26 template <int D> class aabb;
27 template <int D> class sphere;
28
29 /**
30 * A plane in 3-space defined by the equation Ax + By + Cz = D, where [A, B,
31 * C] is normal to the plane.
32 */
33 struct plane : public shape<3>
34 {
35 vector3 normal;
36 scalar d;
37
38 enum halfspace
39 {
40 negative = -1,
41 intersecting = 0,
42 positive = 1
43 };
44
45 plane() {}
46 plane(const vector3& vector, scalar scalar) :
47 normal(vector),
48 d(scalar) {}
49 plane(scalar a, scalar b, scalar c, scalar scalar) :
50 normal(a, b, c),
51 d(scalar) {}
52
53 bool intersect_ray(const ray3& ray, ray3::contact& hit)
54 {
55 // solve: [(ray.point + t*ray.direction) dot normal] + d = 0
56
57 scalar denom = dot(ray.direction, normal);
58
59 // check for parallel condition
60 if (denom == SCALAR(0.0))
61 {
62 if (is_equal(dot(ray.point, normal), -d))
63 {
64 // the ray lies on the plane
65 hit.distance = SCALAR(0.0);
66 hit.normal.set(0.0, 0.0, 0.0);
67 return true;
68 }
69
70 // no solution
71 return false;
72 }
73
74 scalar numer = dot(ray.point, normal) + d;
75 hit.distance = -numer / denom;
76 if (hit.distance < SCALAR(0.0)) return false;
77
78 if (numer >= 0.0) hit.normal = normal;
79 else hit.normal = -normal;
80 return true;
81 }
82
83 /* Causes the normal of the plane to become normalized. The scalar may
84 * also be changed to keep the equation true. Word to the wise: don't
85 * normalize a plane if the normal is the zero vector.
86 */
87 void normalize()
88 {
89 scalar mag = normal.length();
90 normal /= mag;
91 d /= mag;
92 }
93
94 /**
95 * Determine the shortest distance between a point and the plane.
96 */
97 scalar distance_to_point(const vector3& point) const
98 {
99 return dot(point, normal) + d;
100 }
101
102 halfspace intersects(const vector3& point) const
103 {
104 scalar distance = distance_to_point(point);
105
106 if (is_equal(distance, 0.0)) return intersecting;
107 else if (distance < 0.0) return negative;
108 return positive;
109 }
110
111 halfspace intersects(const aabb<3>& aabb) const;
112 halfspace intersects(const sphere<3>& sphere) const;
113 };
114
115
116 } // namespace moof
117
118 #endif // _MOOF_PLANE_HH_
119
This page took 0.036554 seconds and 3 git commands to generate.