OpenVDB  1.2.0
Vec2.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2013 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 
31 #ifndef OPENVDB_MATH_VEC2_HAS_BEEN_INCLUDED
32 #define OPENVDB_MATH_VEC2_HAS_BEEN_INCLUDED
33 
34 #include <cmath>
35 #include <openvdb/Exceptions.h>
36 #include "Math.h"
37 #include "Tuple.h"
38 
39 
40 namespace openvdb {
42 namespace OPENVDB_VERSION_NAME {
43 namespace math {
44 
45 template<typename T> class Mat2;
46 
47 template<typename T>
48 class Vec2: public Tuple<2, T>
49 {
50 public:
51  typedef T value_type;
52  typedef T ValueType;
53 
55  Vec2() {}
56 
58  explicit Vec2(T val) { this->mm[0] = this->mm[1] = val; }
59 
61  Vec2(T x, T y)
62  {
63  this->mm[0] = x;
64  this->mm[1] = y;
65  }
66 
68  template <typename Source>
69  Vec2(Source *a)
70  {
71  this->mm[0] = a[0];
72  this->mm[1] = a[1];
73  } // trivial
74 
76  template<typename Source>
77  explicit Vec2(const Tuple<2, Source> &t)
78  {
79  this->mm[0] = static_cast<T>(t[0]);
80  this->mm[1] = static_cast<T>(t[1]);
81  }
82 
84  T& x() {return this->mm[0];}
85  T& y() {return this->mm[1];}
86 
88  T x() const {return this->mm[0];}
89  T y() const {return this->mm[1];}
90 
92  T& operator()(int i) {return this->mm[i];}
93 
95  T operator()(int i) const {return this->mm[i];}
96 
97  T* asPointer() {return this->mm;}
98  const T* asPointer() const {return this->mm;}
99 
102  const Vec2<T>& init(T x=0, T y=0)
103  {
104  this->mm[0] = x; this->mm[1] = y;
105  return *this;
106  }
107 
109  const Vec2<T>& setZero()
110  {
111  this->mm[0] = 0; this->mm[1] = 0;
112  return *this;
113  }
114 
116  template<typename Source>
117  const Vec2<T>& operator=(const Vec2<Source> &v)
118  {
119  // note: don't static_cast because that suppresses warnings
120  this->mm[0] = v[0];
121  this->mm[1] = v[1];
122 
123  return *this;
124  }
125 
127  bool operator==(const Vec2<T> &v) const
128  {
129  return (isExactlyEqual(this->mm[0], v.mm[0]) && isExactlyEqual(this->mm[1], v.mm[1]));
130  }
131 
133  bool operator!=(const Vec2<T> &v) const { return !(*this==v); }
134 
136  bool eq(const Vec2<T> &v, T eps = static_cast<T>(1.0e-7)) const
137  {
138  return isApproxEqual(this->mm[0], v.mm[0], eps) &&
139  isApproxEqual(this->mm[1], v.mm[1], eps);
140  } // trivial
141 
143  Vec2<T> operator-() const {return Vec2<T>(-this->mm[0], -this->mm[1]);}
144 
147  template <typename T0, typename T1>
148  const Vec2<T>& add(const Vec2<T0> &v1, const Vec2<T1> &v2)
149  {
150  this->mm[0] = v1[0] + v2[0];
151  this->mm[1] = v1[1] + v2[1];
152 
153  return *this;
154  }
155 
158  template <typename T0, typename T1>
159  const Vec2<T>& sub(const Vec2<T0> &v1, const Vec2<T1> &v2)
160  {
161  this->mm[0] = v1[0] - v2[0];
162  this->mm[1] = v1[1] - v2[1];
163 
164  return *this;
165  }
166 
169  template <typename T0, typename T1>
170  const Vec2<T>& scale(T0 scalar, const Vec2<T1> &v)
171  {
172  this->mm[0] = scalar * v[0];
173  this->mm[1] = scalar * v[1];
174 
175  return *this;
176  }
177 
178  template <typename T0, typename T1>
179  const Vec2<T> &div(T0 scalar, const Vec2<T1> &v)
180  {
181  this->mm[0] = v[0] / scalar;
182  this->mm[1] = v[1] / scalar;
183 
184  return *this;
185  }
186 
188  T dot(const Vec2<T> &v) const { return this->mm[0]*v[0] + this->mm[1]*v[1]; } // trivial
189 
191  T length() const
192  {
193  return static_cast<T>(sqrt(double(this->mm[0]*this->mm[0] + this->mm[1]*this->mm[1])));
194  }
195 
198  T lengthSqr() const { return (this->mm[0]*this->mm[0] + this->mm[1]*this->mm[1]); }
199 
201  bool normalize(T eps=1.0e-8)
202  {
203  T d = length();
204  if (isApproxEqual(d, T(0), eps)) {
205  return false;
206  }
207  *this *= (T(1) / d);
208  return true;
209  }
210 
212  Vec2<T> unit(T eps=0) const
213  {
214  T d;
215  return unit(eps, d);
216  }
217 
219  Vec2<T> unit(T eps, T& len) const
220  {
221  len = length();
222  if (isApproxEqual(len, T(0), eps)) {
223  OPENVDB_THROW(ArithmeticError, "Normalizing null 2-vector");
224  }
225  return *this / len;
226  }
227 
229  template <typename S>
230  const Vec2<T> &operator*=(S scalar)
231  {
232  this->mm[0] *= scalar;
233  this->mm[1] *= scalar;
234  return *this;
235  }
236 
238  template <typename S>
239  const Vec2<T> &operator*=(const Vec2<S> &v1)
240  {
241  this->mm[0] *= v1[0];
242  this->mm[1] *= v1[1];
243  return *this;
244  }
245 
247  template <typename S>
248  const Vec2<T> &operator/=(S scalar)
249  {
250  this->mm[0] /= scalar;
251  this->mm[1] /= scalar;
252  return *this;
253  }
254 
256  template <typename S>
257  const Vec2<T> &operator/=(const Vec2<S> &v1)
258  {
259  this->mm[0] /= v1[0];
260  this->mm[1] /= v1[1];
261  return *this;
262  }
263 
265  template <typename S>
266  const Vec2<T> &operator+=(S scalar)
267  {
268  this->mm[0] += scalar;
269  this->mm[1] += scalar;
270  return *this;
271  }
272 
274  template <typename S>
275  const Vec2<T> &operator+=(const Vec2<S> &v1)
276  {
277  this->mm[0] += v1[0];
278  this->mm[1] += v1[1];
279  return *this;
280  }
281 
283  template <typename S>
284  const Vec2<T> &operator-=(S scalar)
285  {
286  this->mm[0] -= scalar;
287  this->mm[1] -= scalar;
288  return *this;
289  }
290 
292  template <typename S>
293  const Vec2<T> &operator-=(const Vec2<S> &v1)
294  {
295  this->mm[0] -= v1[0];
296  this->mm[1] -= v1[1];
297  return *this;
298  }
299 
300  // Number of cols, rows, elements
301  static unsigned numRows() { return 1; }
302  static unsigned numColumns() { return 2; }
303  static unsigned numElements() { return 2; }
304 
307  T component(const Vec2<T> &onto, T eps=1.0e-8) const
308  {
309  T l = onto.length();
310  if (isApproxEqual(l, T(0), eps)) return 0;
311 
312  return dot(onto)*(T(1)/l);
313  }
314 
317  Vec2<T> projection(const Vec2<T> &onto, T eps=1.0e-8) const
318  {
319  T l = onto.lengthSqr();
320  if (isApproxEqual(l, T(0), eps)) return Vec2::zero();
321 
322  return onto*(dot(onto)*(T(1)/l));
323  }
324 
328  Vec2<T> getArbPerpendicular() const { return Vec2<T>(-this->mm[1], this->mm[0]); }
329 
331  bool isNan() const { return isnan(this->mm[0]) || isnan(this->mm[1]); }
332 
334  bool isInfinite() const { return isinf(this->mm[0]) || isinf(this->mm[1]); }
335 
337  bool isFinite() const { return finite(this->mm[0]) && finite(this->mm[1]); }
338 
340  static Vec2<T> zero() { return Vec2<T>(0, 0); }
341 };
342 
343 
345 template <typename S, typename T>
347 {
348  return v * scalar;
349 }
350 
352 template <typename S, typename T>
354 {
356  result *= scalar;
357  return result;
358 }
359 
361 template <typename T0, typename T1>
363 {
364  Vec2<typename promote<T0, T1>::type> result(v0[0] * v1[0], v0[1] * v1[1]);
365  return result;
366 }
367 
369 template <typename S, typename T>
371 {
372  return Vec2<typename promote<S, T>::type>(scalar/v[0], scalar/v[1]);
373 }
374 
376 template <typename S, typename T>
378 {
380  result /= scalar;
381  return result;
382 }
383 
385 template <typename T0, typename T1>
387 {
388  Vec2<typename promote<T0, T1>::type> result(v0[0] / v1[0], v0[1] / v1[1]);
389  return result;
390 }
391 
393 template <typename T0, typename T1>
395 {
397  result += v1;
398  return result;
399 }
400 
402 template <typename S, typename T>
404 {
406  result += scalar;
407  return result;
408 }
409 
411 template <typename T0, typename T1>
413 {
415  result -= v1;
416  return result;
417 }
418 
420 template <typename S, typename T>
422 {
424  result -= scalar;
425  return result;
426 }
427 
430 template <typename T>
431 inline T angle(const Vec2<T> &v1, const Vec2<T> &v2)
432 {
433  T c = v1.dot(v2);
434  return acos(c);
435 }
436 
437 template <typename T>
438 inline bool
439 isApproxEqual(const Vec2<T>& a, const Vec2<T>& b)
440 {
441  return a.eq(b);
442 }
443 template <typename T>
444 inline bool
445 isApproxEqual(const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& eps)
446 {
447  return isApproxEqual(a.x(), b.x(), eps.x()) &&
448  isApproxEqual(a.y(), b.y(), eps.y());
449 }
450 
453 template <typename T>
454 inline void orthonormalize(Vec2<T> &v1, Vec2<T> &v2)
455 {
456  // If the input vectors are v0, v1, and v2, then the Gram-Schmidt
457  // orthonormalization produces vectors u0, u1, and u2 as follows,
458  //
459  // u0 = v0/|v0|
460  // u1 = (v1-(u0*v1)u0)/|v1-(u0*v1)u0|
461  //
462  // where |A| indicates length of vector A and A*B indicates dot
463  // product of vectors A and B.
464 
465  // compute u0
466  v1.normalize();
467 
468  // compute u1
469  T d0 = v1.dot(v2);
470  v2 -= v1*d0;
471  v2.normalize();
472 }
473 
474 
479 
481 template <typename T>
482 inline Vec2<T> minComponent(const Vec2<T> &v1, const Vec2<T> &v2)
483 {
484  return Vec2<T>(
485  std::min(v1.x(), v2.x()),
486  std::min(v1.y(), v2.y()));
487 }
488 
490 template <typename T>
491 inline Vec2<T> maxComponent(const Vec2<T> &v1, const Vec2<T> &v2)
492 {
493  return Vec2<T>(
494  std::max(v1.x(), v2.x()),
495  std::max(v1.y(), v2.y()));
496 }
497 
498 
500 typedef Vec2<int> Vec2i;
503 
504 #if DWREAL_IS_DOUBLE == 1
505 typedef Vec2d Vec2f;
506 #else
507 typedef Vec2s Vec2f;
508 #endif // DWREAL_IS_DOUBLE
509 
510 } // namespace math
511 } // namespace OPENVDB_VERSION_NAME
512 } // namespace openvdb
513 
514 #endif // OPENVDB_MATH_VEC2_HAS_BEEN_INCLUDED
515 
516 // Copyright (c) 2012-2013 DreamWorks Animation LLC
517 // All rights reserved. This software is distributed under the
518 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )