OpenVDB  0.104.0
Plane.h
Go to the documentation of this file.
1 
2 //
3 // Copyright (c) 2012 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 //
33 
34 #ifndef OPENVDB_MATH_PLANE_HAS_BEEN_INCLUDED
35 #define OPENVDB_MATH_PLANE_HAS_BEEN_INCLUDED
36 
37 #include <cassert>
38 #include <cstring>
39 #include <iostream>// for cout
40 #include <fstream>//for ofstream
41 #include <algorithm>//for min/max
42 #include <cmath>//for sqrt
43 #include "Math.h" // for Clamp01
44 #include "Vec3.h"
45 #include "Ray.h"
46 
47 
48 namespace openvdb {
50 namespace OPENVDB_VERSION_NAME {
51 namespace math {
52 
65 template<typename Real>
66 class Plane
67 {
68 public:
69  typedef Vec3<Real> Point;
70  typedef Vec3<Real> Vector;
71 
74  class Normalize {
75  };
76 
77  private:
78 
79  Vector mNorm;//normal of plane
80  Point mPoint;// point on plane (useful for interpolation)
81  Real mDist;// = N.P0, i.e. normal dot any point in the plane
82 
83  public:
84 
86 OPENVDB_DEPRECATED Plane() : mNorm(0,0,0), mPoint(0,0,0), mDist(0)
87  {
88  }
89 
92 OPENVDB_DEPRECATED Plane(const Point &P0, const Vector &N)
93  : mNorm(N), mPoint(P0), mDist(N.dot(P0))
94  {
95  }
96 
99  : mNorm(N), mPoint(P0)
100  {
101  mNorm *= Inv(mNorm.length());
102  mDist = mNorm.dot(P0);
103  }
104 
107 OPENVDB_DEPRECATED Plane(const Vector &P1, const Vector &P2, Real alpha)
108  {
109  assert(P1!=P2);
110  mNorm = P2-P1;
111  mNorm *= Inv(mNorm.length());
112  const Real C1=Clamp01(alpha), C2=1-C1;
113  mPoint= C2*P1+C1*P2;
114  mDist = mNorm.dot(mPoint);
115  }
116 
119 OPENVDB_DEPRECATED Plane(const Point &P0, const Point &P1, const Point &P2)
120  {
121  assert(P0!=P1);
122  assert(P0!=P2);
123  assert(P1!=P2);
124  mNorm.cross(P1-P0,P2-P0);//right-hand turn!
125  mNorm *= Inv(mNorm.length());
126  assert(Abs(1.-mNorm.length())<0.001);
127  mPoint = P0;
128  mDist=mNorm.dot(P0);
129  }
132 OPENVDB_DEPRECATED Plane(const Point &P0, const Point &P1, const Point &P2, int n)
133  {
134  assert(P0!=P1);
135  assert(P0!=P2);
136  assert(P1!=P2);
137  mNorm.cross(P1-P0,P2-P0);//right-hand turn!
138  mNorm *= Inv(mNorm.length());
139  assert(Abs(1.-mNorm.length())<0.001);
140  mPoint = n==0 ? P0: n==1 ? P1 : P2;
141  mDist=mNorm.dot(P0);
142  }
143 
145  inline void flip()
146  {
147  mNorm[0] = -mNorm[0];
148  mNorm[1] = -mNorm[1];
149  mNorm[2] = -mNorm[2];
150  mDist = -mDist;
151  }
152 
155  inline Real getDist() const {return mDist;}
156 
158  inline Vector getNorm() const {return mNorm;}
159  inline Vector getNormal() const {return this->getNorm();}
160 
162  inline Point getPoint() const {return mPoint;}
163 
165  inline Real getPoint(int i) const {return mPoint[i];}
166 
168  inline Real getNorm(int i) const {return mNorm[i];}
169 
172  inline Point getNormalPoint() const {return mDist*mNorm;}
173 
177  inline void setNorm(const Vector &N)
178  {
179  mDist = N.dot(mPoint);
180  mNorm = N;
181  }
182 
184  inline void setPoint(const Point &P0)
185  {
186  mPoint= P0;
187  mDist = mNorm.dot(P0);
188  }
189 
191  inline void set(const Point &P0, const Vector &N)
192  {
193  mNorm = N;
194  mPoint= P0;
195  mDist = N.dot(P0);
196  }
197 
199  inline void set(const Point &P0, const Vector &N, Normalize)
200  {
201  mNorm = N;
202  mNorm *= Inv(mNorm.length());
203  mPoint= P0;
204  mDist = N.dot(P0);
205  }
206 
212  inline bool operator==(const Plane &other) const
213  {
214  return mNorm.eq(other.mNorm) && mPoint.eq(other.mPoint);
215  }
216 
221  inline bool operator!=(const Plane &other) const
222  {
223  return !(*this == other );
224  }
225 
228  inline bool isValid() const {return (mNorm[0] || mNorm[1] || mNorm[2]);}
229 
232  inline bool isInside(const Point &P) const
233  {
234  return mNorm.dot(P) < mDist;
235  }
236 
238  inline bool isInside(const Point &P1, const Point &P2) const
239  {
240  return mNorm.dot(P1)<mDist && mNorm.dot(P2)<mDist;
241  }
242 
244  inline bool isInside(const Point &P1, const Point &P2, const Point &P3) const
245  {
246  return mNorm.dot(P1)<mDist && mNorm.dot(P2)<mDist && mNorm.dot(P3)<mDist;
247  }
248 
250  inline bool isOutside(const Point &P) const
251  {
252  return mNorm.dot(P) > mDist;
253  }
254 
256  inline bool isOutside(const Point &P1, const Point &P2) const
257  {
258  return mNorm.dot(P1)>mDist && mNorm.dot(P2)>mDist;
259  }
260 
261  // Convenient for checking vertices of a trinagle
262  inline bool isOutside(const Point &P1, const Point &P2, const Point &P3) const
263  {
264  return mNorm.dot(P1)>mDist && mNorm.dot(P2)>mDist && mNorm.dot(P3)>mDist;
265  }
266 
268  inline bool isOn(const Point &pt, Real tolerance=1e-6) const
269  {
270  return std::abs(mNorm.dot(pt) - mDist) < tolerance;
271  }
272 
274  inline bool intersects(const Point &P1, const Point &P2) const
275  {
276  return (mNorm.dot(P1)-mDist)*(mNorm.dot(P2)-mDist)<0;
277  }
278 
280  inline bool intersects(const Ray<Real> &ray) const
281  {
282  return this->intersects(ray.start(),ray.end());
283  }
284 
287  inline bool intersects(const Ray<Real> &ray, Real &t) const
288  {
289  const Real cosAngle = mNorm.dot(ray.getDirection());//= PlaneNorm . RayNorm
290  if (isExactlyEqual(cosAngle, 0.0)) return false;//parallel
291  t = (mDist-mNorm.dot(ray.getOrigin()))/cosAngle;
292  if (t<ray.getMinTime() || t>ray.getMaxTime()) return false;//out of range
293  return true;
294  }
295 
297  inline Real angle(const Plane &other) const {return acos(mNorm.dot(other.mNorm));}
298 
302  Plane slerp(const Plane &other, Real t) const {
303  const Real t1 = Clamp01(t), t0 = 1-t1;
304  const Real NdotN = mNorm.dot(other.mNorm);
305  if (NdotN > 0.9995) {//normals are almost parallel so do lerp!
306  return Plane(t0*mPoint + t1*other.mPoint,
307  t0*mNorm + t1*other.mNorm,Normalize());//slerp normals
308  }
309  const Real angle=acos(NdotN), inv = Real(1)/sin(angle);
310  const Real c0 = sin(t0*angle)*inv, c1 = sin(t1*angle)*inv;
311  return Plane(t0*mPoint + t1*other.mPoint,//lerp positions
312  c0*mNorm + c1*other.mNorm);//slerp normals
313 
314  }
315 
319  Plane lerp(const Plane &other, Real t) const {
320  const Real t1 = Clamp01(t), t0 = 1-t1;
321  return Plane(t0*mPoint + t1*other.mPoint,//lerp positions
322  t0*mNorm + t1*other.mNorm,Normalize());//lerp normals
323  }
326  Plane lerpPoints(const Plane &other, Real t) const
327  {
328  const Real t1 = Clamp01(t), t0 = 1-t1;
329  return Plane(t0*mPoint + t1*other.mPoint,mNorm);//lerp positions
330  }
331 };//end of Plane class
332 
333 
335 template<typename Real>
336 inline std::ostream& operator<<(std::ostream& os, const Plane<Real>& p) {
337  os << "Plane: N=" << p.getNorm() << " P=" << p.getPoint() << " D=" << p.getDist();
338  return os;
339 }
340 
341 } // namespace math
342 } // namespace OPENVDB_VERSION_NAME
343 } // namespace openvdb
344 
345 #endif // OPENVDB_MATH_PLANE_HAS_BEEN_INCLUDED
346 
347 // Copyright (c) 2012 DreamWorks Animation LLC
348 // All rights reserved. This software is distributed under the
349 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )