1 | /** |
---|
2 | @file Plane.cpp |
---|
3 | |
---|
4 | @maintainer Morgan McGuire, matrix@graphics3d.com |
---|
5 | |
---|
6 | @created 2003-02-06 |
---|
7 | @edited 2006-01-29 |
---|
8 | */ |
---|
9 | |
---|
10 | #include "G3D/platform.h" |
---|
11 | #include "G3D/format.h" |
---|
12 | #include "G3D/Plane.h" |
---|
13 | #include "G3D/stringutils.h" |
---|
14 | |
---|
15 | namespace G3D { |
---|
16 | |
---|
17 | Plane::Plane( |
---|
18 | Vector4 point0, |
---|
19 | Vector4 point1, |
---|
20 | Vector4 point2) { |
---|
21 | |
---|
22 | debugAssertM( |
---|
23 | point0.w != 0 || |
---|
24 | point1.w != 0 || |
---|
25 | point2.w != 0, |
---|
26 | "At least one point must be finite."); |
---|
27 | |
---|
28 | // Rotate the points around so that the finite points come first. |
---|
29 | |
---|
30 | while ((point0.w == 0) && |
---|
31 | ((point1.w == 0) || (point2.w != 0))) { |
---|
32 | Vector4 temp = point0; |
---|
33 | point0 = point1; |
---|
34 | point1 = point2; |
---|
35 | point2 = temp; |
---|
36 | } |
---|
37 | |
---|
38 | Vector3 dir1; |
---|
39 | Vector3 dir2; |
---|
40 | |
---|
41 | if (point1.w == 0) { |
---|
42 | // 1 finite, 2 infinite points; the plane must contain |
---|
43 | // the direction of the two direcitons |
---|
44 | dir1 = point1.xyz(); |
---|
45 | dir2 = point2.xyz(); |
---|
46 | } else if (point2.w != 0) { |
---|
47 | // 3 finite points, the plane must contain the directions |
---|
48 | // betwseen the points. |
---|
49 | dir1 = point1.xyz() - point0.xyz(); |
---|
50 | dir2 = point2.xyz() - point0.xyz(); |
---|
51 | } else { |
---|
52 | // 2 finite, 1 infinite point; the plane must contain |
---|
53 | // the direction between the first two points and the |
---|
54 | // direction of the third point. |
---|
55 | dir1 = point1.xyz() - point0.xyz(); |
---|
56 | dir2 = point2.xyz(); |
---|
57 | } |
---|
58 | |
---|
59 | _normal = dir1.cross(dir2).direction(); |
---|
60 | _distance = _normal.dot(point0.xyz()); |
---|
61 | } |
---|
62 | |
---|
63 | |
---|
64 | Plane::Plane( |
---|
65 | const Vector3& point0, |
---|
66 | const Vector3& point1, |
---|
67 | const Vector3& point2) { |
---|
68 | |
---|
69 | _normal = (point1 - point0).cross(point2 - point0).direction(); |
---|
70 | _distance = _normal.dot(point0); |
---|
71 | } |
---|
72 | |
---|
73 | |
---|
74 | Plane::Plane( |
---|
75 | const Vector3& __normal, |
---|
76 | const Vector3& point) { |
---|
77 | |
---|
78 | _normal = __normal.direction(); |
---|
79 | _distance = _normal.dot(point); |
---|
80 | } |
---|
81 | |
---|
82 | |
---|
83 | Plane Plane::fromEquation(float a, float b, float c, float d) { |
---|
84 | Vector3 n(a, b, c); |
---|
85 | float magnitude = n.magnitude(); |
---|
86 | d /= magnitude; |
---|
87 | n /= magnitude; |
---|
88 | return Plane(n, -d); |
---|
89 | } |
---|
90 | |
---|
91 | |
---|
92 | void Plane::flip() { |
---|
93 | _normal = -_normal; |
---|
94 | _distance = -_distance; |
---|
95 | } |
---|
96 | |
---|
97 | |
---|
98 | void Plane::getEquation(Vector3& n, float& d) const { |
---|
99 | double _d; |
---|
100 | getEquation(n, _d); |
---|
101 | d = (float)_d; |
---|
102 | } |
---|
103 | |
---|
104 | void Plane::getEquation(Vector3& n, double& d) const { |
---|
105 | n = _normal; |
---|
106 | d = -_distance; |
---|
107 | } |
---|
108 | |
---|
109 | |
---|
110 | void Plane::getEquation(float& a, float& b, float& c, float& d) const { |
---|
111 | double _a, _b, _c, _d; |
---|
112 | getEquation(_a, _b, _c, _d); |
---|
113 | a = (float)_a; |
---|
114 | b = (float)_b; |
---|
115 | c = (float)_c; |
---|
116 | d = (float)_d; |
---|
117 | } |
---|
118 | |
---|
119 | void Plane::getEquation(double& a, double& b, double& c, double& d) const { |
---|
120 | a = _normal.x; |
---|
121 | b = _normal.y; |
---|
122 | c = _normal.z; |
---|
123 | d = -_distance; |
---|
124 | } |
---|
125 | |
---|
126 | |
---|
127 | std::string Plane::toString() const { |
---|
128 | return format("Plane(%g, %g, %g, %g)", _normal.x, _normal.y, _normal.z, _distance); |
---|
129 | } |
---|
130 | |
---|
131 | } |
---|