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