1 ///////////////////////////////////////////////////////////////////////////
3 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
6 // All rights reserved.
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of Industrial Light & Magic nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 ///////////////////////////////////////////////////////////////////////////
37 #ifndef INCLUDED_IMATHVEC_H
38 #define INCLUDED_IMATHVEC_H
40 //----------------------------------------------------
42 // 2D and 3D point/vector class templates!
44 //----------------------------------------------------
47 #include "ImathLimits.h"
48 #include "ImathMath.h"
52 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
53 // suppress exception specification warnings
54 #pragma warning(disable:4290)
61 template <class T> class Vec2
71 T & operator [] (int i);
72 const T & operator [] (int i) const;
79 Vec2 (); // no initialization
80 explicit Vec2 (T a); // (a a)
81 Vec2 (T a, T b); // (a b)
84 //---------------------------------
85 // Copy constructors and assignment
86 //---------------------------------
89 template <class S> Vec2 (const Vec2<S> &v);
91 const Vec2 & operator = (const Vec2 &v);
94 //----------------------
95 // Compatibility with Sb
96 //----------------------
99 void setValue (S a, S b);
102 void setValue (const Vec2<S> &v);
105 void getValue (S &a, S &b) const;
108 void getValue (Vec2<S> &v) const;
111 const T * getValue () const;
119 bool operator == (const Vec2<S> &v) const;
122 bool operator != (const Vec2<S> &v) const;
125 //-----------------------------------------------------------------------
126 // Compare two vectors and test if they are "approximately equal":
128 // equalWithAbsError (v, e)
130 // Returns true if the coefficients of this and v are the same with
131 // an absolute error of no more than e, i.e., for all i
133 // abs (this[i] - v[i]) <= e
135 // equalWithRelError (v, e)
137 // Returns true if the coefficients of this and v are the same with
138 // a relative error of no more than e, i.e., for all i
140 // abs (this[i] - v[i]) <= e * abs (this[i])
141 //-----------------------------------------------------------------------
143 bool equalWithAbsError (const Vec2<T> &v, T e) const;
144 bool equalWithRelError (const Vec2<T> &v, T e) const;
150 T dot (const Vec2 &v) const;
151 T operator ^ (const Vec2 &v) const;
154 //------------------------------------------------
155 // Right-handed cross product, i.e. z component of
156 // Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0)
157 //------------------------------------------------
159 T cross (const Vec2 &v) const;
160 T operator % (const Vec2 &v) const;
163 //------------------------
164 // Component-wise addition
165 //------------------------
167 const Vec2 & operator += (const Vec2 &v);
168 Vec2 operator + (const Vec2 &v) const;
171 //---------------------------
172 // Component-wise subtraction
173 //---------------------------
175 const Vec2 & operator -= (const Vec2 &v);
176 Vec2 operator - (const Vec2 &v) const;
179 //------------------------------------
180 // Component-wise multiplication by -1
181 //------------------------------------
183 Vec2 operator - () const;
184 const Vec2 & negate ();
187 //------------------------------
188 // Component-wise multiplication
189 //------------------------------
191 const Vec2 & operator *= (const Vec2 &v);
192 const Vec2 & operator *= (T a);
193 Vec2 operator * (const Vec2 &v) const;
194 Vec2 operator * (T a) const;
197 //------------------------
198 // Component-wise division
199 //------------------------
201 const Vec2 & operator /= (const Vec2 &v);
202 const Vec2 & operator /= (T a);
203 Vec2 operator / (const Vec2 &v) const;
204 Vec2 operator / (T a) const;
207 //----------------------------------------------------------------
208 // Length and normalization: If v.length() is 0.0, v.normalize()
209 // and v.normalized() produce a null vector; v.normalizeExc() and
210 // v.normalizedExc() throw a NullVecExc.
211 // v.normalizeNonNull() and v.normalizedNonNull() are slightly
212 // faster than the other normalization routines, but if v.length()
213 // is 0.0, the result is undefined.
214 //----------------------------------------------------------------
219 const Vec2 & normalize (); // modifies *this
220 const Vec2 & normalizeExc () throw (Iex::MathExc);
221 const Vec2 & normalizeNonNull ();
223 Vec2<T> normalized () const; // does not modify *this
224 Vec2<T> normalizedExc () const throw (Iex::MathExc);
225 Vec2<T> normalizedNonNull () const;
228 //--------------------------------------------------------
229 // Number of dimensions, i.e. number of elements in a Vec2
230 //--------------------------------------------------------
232 static unsigned int dimensions() {return 2;}
235 //-------------------------------------------------
236 // Limitations of type T (see also class limits<T>)
237 //-------------------------------------------------
239 static T baseTypeMin() {return limits<T>::min();}
240 static T baseTypeMax() {return limits<T>::max();}
241 static T baseTypeSmallest() {return limits<T>::smallest();}
242 static T baseTypeEpsilon() {return limits<T>::epsilon();}
245 //--------------------------------------------------------------
246 // Base type -- in templates, which accept a parameter, V, which
247 // could be either a Vec2<T> or a Vec3<T>, you can refer to T as
249 //--------------------------------------------------------------
255 template <class T> class Vec3
259 //-------------------
260 // Access to elements
261 //-------------------
265 T & operator [] (int i);
266 const T & operator [] (int i) const;
273 Vec3 (); // no initialization
274 explicit Vec3 (T a); // (a a a)
275 Vec3 (T a, T b, T c); // (a b c)
278 //---------------------------------
279 // Copy constructors and assignment
280 //---------------------------------
282 Vec3 (const Vec3 &v);
283 template <class S> Vec3 (const Vec3<S> &v);
285 const Vec3 & operator = (const Vec3 &v);
288 //----------------------
289 // Compatibility with Sb
290 //----------------------
293 void setValue (S a, S b, S c);
296 void setValue (const Vec3<S> &v);
299 void getValue (S &a, S &b, S &c) const;
302 void getValue (Vec3<S> &v) const;
305 const T * getValue() const;
313 bool operator == (const Vec3<S> &v) const;
316 bool operator != (const Vec3<S> &v) const;
318 //-----------------------------------------------------------------------
319 // Compare two vectors and test if they are "approximately equal":
321 // equalWithAbsError (v, e)
323 // Returns true if the coefficients of this and v are the same with
324 // an absolute error of no more than e, i.e., for all i
326 // abs (this[i] - v[i]) <= e
328 // equalWithRelError (v, e)
330 // Returns true if the coefficients of this and v are the same with
331 // a relative error of no more than e, i.e., for all i
333 // abs (this[i] - v[i]) <= e * abs (this[i])
334 //-----------------------------------------------------------------------
336 bool equalWithAbsError (const Vec3<T> &v, T e) const;
337 bool equalWithRelError (const Vec3<T> &v, T e) const;
343 T dot (const Vec3 &v) const;
344 T operator ^ (const Vec3 &v) const;
347 //---------------------------
348 // Right-handed cross product
349 //---------------------------
351 Vec3 cross (const Vec3 &v) const;
352 const Vec3 & operator %= (const Vec3 &v);
353 Vec3 operator % (const Vec3 &v) const;
356 //------------------------
357 // Component-wise addition
358 //------------------------
360 const Vec3 & operator += (const Vec3 &v);
361 Vec3 operator + (const Vec3 &v) const;
364 //---------------------------
365 // Component-wise subtraction
366 //---------------------------
368 const Vec3 & operator -= (const Vec3 &v);
369 Vec3 operator - (const Vec3 &v) const;
372 //------------------------------------
373 // Component-wise multiplication by -1
374 //------------------------------------
376 Vec3 operator - () const;
377 const Vec3 & negate ();
380 //------------------------------
381 // Component-wise multiplication
382 //------------------------------
384 const Vec3 & operator *= (const Vec3 &v);
385 const Vec3 & operator *= (T a);
386 Vec3 operator * (const Vec3 &v) const;
387 Vec3 operator * (T a) const;
390 //------------------------
391 // Component-wise division
392 //------------------------
394 const Vec3 & operator /= (const Vec3 &v);
395 const Vec3 & operator /= (T a);
396 Vec3 operator / (const Vec3 &v) const;
397 Vec3 operator / (T a) const;
400 //----------------------------------------------------------------
401 // Length and normalization: If v.length() is 0.0, v.normalize()
402 // and v.normalized() produce a null vector; v.normalizeExc() and
403 // v.normalizedExc() throw a NullVecExc.
404 // v.normalizeNonNull() and v.normalizedNonNull() are slightly
405 // faster than the other normalization routines, but if v.length()
406 // is 0.0, the result is undefined.
407 //----------------------------------------------------------------
412 const Vec3 & normalize (); // modifies *this
413 const Vec3 & normalizeExc () throw (Iex::MathExc);
414 const Vec3 & normalizeNonNull ();
416 Vec3<T> normalized () const; // does not modify *this
417 Vec3<T> normalizedExc () const throw (Iex::MathExc);
418 Vec3<T> normalizedNonNull () const;
421 //--------------------------------------------------------
422 // Number of dimensions, i.e. number of elements in a Vec3
423 //--------------------------------------------------------
425 static unsigned int dimensions() {return 3;}
428 //-------------------------------------------------
429 // Limitations of type T (see also class limits<T>)
430 //-------------------------------------------------
432 static T baseTypeMin() {return limits<T>::min();}
433 static T baseTypeMax() {return limits<T>::max();}
434 static T baseTypeSmallest() {return limits<T>::smallest();}
435 static T baseTypeEpsilon() {return limits<T>::epsilon();}
438 //--------------------------------------------------------------
439 // Base type -- in templates, which accept a parameter, V, which
440 // could be either a Vec2<T> or a Vec3<T>, you can refer to T as
442 //--------------------------------------------------------------
453 std::ostream & operator << (std::ostream &s, const Vec2<T> &v);
456 std::ostream & operator << (std::ostream &s, const Vec3<T> &v);
459 //----------------------------------------------------
460 // Reverse multiplication: S * Vec2<T> and S * Vec3<T>
461 //----------------------------------------------------
463 template <class T> Vec2<T> operator * (T a, const Vec2<T> &v);
464 template <class T> Vec3<T> operator * (T a, const Vec3<T> &v);
467 //-------------------------
468 // Typedefs for convenience
469 //-------------------------
471 typedef Vec2 <short> V2s;
472 typedef Vec2 <int> V2i;
473 typedef Vec2 <float> V2f;
474 typedef Vec2 <double> V2d;
475 typedef Vec3 <short> V3s;
476 typedef Vec3 <int> V3i;
477 typedef Vec3 <float> V3f;
478 typedef Vec3 <double> V3d;
481 //-------------------------------------------------------------------
482 // Specializations for Vec2<short>, Vec2<int>, Vec3<short>, Vec3<int>
483 //-------------------------------------------------------------------
488 Vec2<short>::length () const;
490 template <> const Vec2<short> &
491 Vec2<short>::normalize ();
493 template <> const Vec2<short> &
494 Vec2<short>::normalizeExc () throw (Iex::MathExc);
496 template <> const Vec2<short> &
497 Vec2<short>::normalizeNonNull ();
499 template <> Vec2<short>
500 Vec2<short>::normalized () const;
502 template <> Vec2<short>
503 Vec2<short>::normalizedExc () const throw (Iex::MathExc);
505 template <> Vec2<short>
506 Vec2<short>::normalizedNonNull () const;
512 Vec2<int>::length () const;
514 template <> const Vec2<int> &
515 Vec2<int>::normalize ();
517 template <> const Vec2<int> &
518 Vec2<int>::normalizeExc () throw (Iex::MathExc);
520 template <> const Vec2<int> &
521 Vec2<int>::normalizeNonNull ();
523 template <> Vec2<int>
524 Vec2<int>::normalized () const;
526 template <> Vec2<int>
527 Vec2<int>::normalizedExc () const throw (Iex::MathExc);
529 template <> Vec2<int>
530 Vec2<int>::normalizedNonNull () const;
536 Vec3<short>::length () const;
538 template <> const Vec3<short> &
539 Vec3<short>::normalize ();
541 template <> const Vec3<short> &
542 Vec3<short>::normalizeExc () throw (Iex::MathExc);
544 template <> const Vec3<short> &
545 Vec3<short>::normalizeNonNull ();
547 template <> Vec3<short>
548 Vec3<short>::normalized () const;
550 template <> Vec3<short>
551 Vec3<short>::normalizedExc () const throw (Iex::MathExc);
553 template <> Vec3<short>
554 Vec3<short>::normalizedNonNull () const;
560 Vec3<int>::length () const;
562 template <> const Vec3<int> &
563 Vec3<int>::normalize ();
565 template <> const Vec3<int> &
566 Vec3<int>::normalizeExc () throw (Iex::MathExc);
568 template <> const Vec3<int> &
569 Vec3<int>::normalizeNonNull ();
571 template <> Vec3<int>
572 Vec3<int>::normalized () const;
574 template <> Vec3<int>
575 Vec3<int>::normalizedExc () const throw (Iex::MathExc);
577 template <> Vec3<int>
578 Vec3<int>::normalizedNonNull () const;
581 //------------------------
582 // Implementation of Vec2:
583 //------------------------
587 Vec2<T>::operator [] (int i)
594 Vec2<T>::operator [] (int i) const
615 Vec2<T>::Vec2 (T a, T b)
623 Vec2<T>::Vec2 (const Vec2 &v)
632 Vec2<T>::Vec2 (const Vec2<S> &v)
639 inline const Vec2<T> &
640 Vec2<T>::operator = (const Vec2 &v)
650 Vec2<T>::setValue (S a, S b)
659 Vec2<T>::setValue (const Vec2<S> &v)
668 Vec2<T>::getValue (S &a, S &b) const
677 Vec2<T>::getValue (Vec2<S> &v) const
692 Vec2<T>::getValue() const
694 return (const T *) &x;
700 Vec2<T>::operator == (const Vec2<S> &v) const
702 return x == v.x && y == v.y;
708 Vec2<T>::operator != (const Vec2<S> &v) const
710 return x != v.x || y != v.y;
715 Vec2<T>::equalWithAbsError (const Vec2<T> &v, T e) const
717 for (int i = 0; i < 2; i++)
718 if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
726 Vec2<T>::equalWithRelError (const Vec2<T> &v, T e) const
728 for (int i = 0; i < 2; i++)
729 if (!Imath::equalWithRelError ((*this)[i], v[i], e))
737 Vec2<T>::dot (const Vec2 &v) const
739 return x * v.x + y * v.y;
744 Vec2<T>::operator ^ (const Vec2 &v) const
751 Vec2<T>::cross (const Vec2 &v) const
753 return x * v.y - y * v.x;
759 Vec2<T>::operator % (const Vec2 &v) const
761 return x * v.y - y * v.x;
765 inline const Vec2<T> &
766 Vec2<T>::operator += (const Vec2 &v)
775 Vec2<T>::operator + (const Vec2 &v) const
777 return Vec2 (x + v.x, y + v.y);
781 inline const Vec2<T> &
782 Vec2<T>::operator -= (const Vec2 &v)
791 Vec2<T>::operator - (const Vec2 &v) const
793 return Vec2 (x - v.x, y - v.y);
798 Vec2<T>::operator - () const
800 return Vec2 (-x, -y);
804 inline const Vec2<T> &
813 inline const Vec2<T> &
814 Vec2<T>::operator *= (const Vec2 &v)
822 inline const Vec2<T> &
823 Vec2<T>::operator *= (T a)
832 Vec2<T>::operator * (const Vec2 &v) const
834 return Vec2 (x * v.x, y * v.y);
839 Vec2<T>::operator * (T a) const
841 return Vec2 (x * a, y * a);
845 inline const Vec2<T> &
846 Vec2<T>::operator /= (const Vec2 &v)
854 inline const Vec2<T> &
855 Vec2<T>::operator /= (T a)
864 Vec2<T>::operator / (const Vec2 &v) const
866 return Vec2 (x / v.x, y / v.y);
871 Vec2<T>::operator / (T a) const
873 return Vec2 (x / a, y / a);
878 Vec2<T>::length () const
880 return Math<T>::sqrt (dot (*this));
885 Vec2<T>::length2 () const
892 Vec2<T>::normalize ()
907 Vec2<T>::normalizeExc () throw (Iex::MathExc)
912 throw NullVecExc ("Cannot normalize null vector.");
922 Vec2<T>::normalizeNonNull ()
932 Vec2<T>::normalized () const
939 return Vec2 (x / l, y / l);
944 Vec2<T>::normalizedExc () const throw (Iex::MathExc)
949 throw NullVecExc ("Cannot normalize null vector.");
951 return Vec2 (x / l, y / l);
957 Vec2<T>::normalizedNonNull () const
960 return Vec2 (x / l, y / l);
964 //-----------------------
965 // Implementation of Vec3
966 //-----------------------
970 Vec3<T>::operator [] (int i)
977 Vec3<T>::operator [] (int i) const
998 Vec3<T>::Vec3 (T a, T b, T c)
1007 Vec3<T>::Vec3 (const Vec3 &v)
1017 Vec3<T>::Vec3 (const Vec3<S> &v)
1025 inline const Vec3<T> &
1026 Vec3<T>::operator = (const Vec3 &v)
1037 Vec3<T>::setValue (S a, S b, S c)
1047 Vec3<T>::setValue (const Vec3<S> &v)
1057 Vec3<T>::getValue (S &a, S &b, S &c) const
1067 Vec3<T>::getValue (Vec3<S> &v) const
1083 Vec3<T>::getValue() const
1085 return (const T *) &x;
1091 Vec3<T>::operator == (const Vec3<S> &v) const
1093 return x == v.x && y == v.y && z == v.z;
1099 Vec3<T>::operator != (const Vec3<S> &v) const
1101 return x != v.x || y != v.y || z != v.z;
1106 Vec3<T>::equalWithAbsError (const Vec3<T> &v, T e) const
1108 for (int i = 0; i < 3; i++)
1109 if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
1117 Vec3<T>::equalWithRelError (const Vec3<T> &v, T e) const
1119 for (int i = 0; i < 3; i++)
1120 if (!Imath::equalWithRelError ((*this)[i], v[i], e))
1128 Vec3<T>::dot (const Vec3 &v) const
1130 return x * v.x + y * v.y + z * v.z;
1135 Vec3<T>::operator ^ (const Vec3 &v) const
1142 Vec3<T>::cross (const Vec3 &v) const
1144 return Vec3 (y * v.z - z * v.y,
1150 inline const Vec3<T> &
1151 Vec3<T>::operator %= (const Vec3 &v)
1153 T a = y * v.z - z * v.y;
1154 T b = z * v.x - x * v.z;
1155 T c = x * v.y - y * v.x;
1164 Vec3<T>::operator % (const Vec3 &v) const
1166 return Vec3 (y * v.z - z * v.y,
1172 inline const Vec3<T> &
1173 Vec3<T>::operator += (const Vec3 &v)
1183 Vec3<T>::operator + (const Vec3 &v) const
1185 return Vec3 (x + v.x, y + v.y, z + v.z);
1189 inline const Vec3<T> &
1190 Vec3<T>::operator -= (const Vec3 &v)
1200 Vec3<T>::operator - (const Vec3 &v) const
1202 return Vec3 (x - v.x, y - v.y, z - v.z);
1207 Vec3<T>::operator - () const
1209 return Vec3 (-x, -y, -z);
1213 inline const Vec3<T> &
1223 inline const Vec3<T> &
1224 Vec3<T>::operator *= (const Vec3 &v)
1233 inline const Vec3<T> &
1234 Vec3<T>::operator *= (T a)
1244 Vec3<T>::operator * (const Vec3 &v) const
1246 return Vec3 (x * v.x, y * v.y, z * v.z);
1251 Vec3<T>::operator * (T a) const
1253 return Vec3 (x * a, y * a, z * a);
1257 inline const Vec3<T> &
1258 Vec3<T>::operator /= (const Vec3 &v)
1267 inline const Vec3<T> &
1268 Vec3<T>::operator /= (T a)
1278 Vec3<T>::operator / (const Vec3 &v) const
1280 return Vec3 (x / v.x, y / v.y, z / v.z);
1285 Vec3<T>::operator / (T a) const
1287 return Vec3 (x / a, y / a, z / a);
1293 Vec3<T>::length () const
1295 return Math<T>::sqrt (dot (*this));
1300 Vec3<T>::length2 () const
1307 Vec3<T>::normalize ()
1323 Vec3<T>::normalizeExc () throw (Iex::MathExc)
1328 throw NullVecExc ("Cannot normalize null vector.");
1339 Vec3<T>::normalizeNonNull ()
1350 Vec3<T>::normalized () const
1355 return Vec3 (T (0));
1357 return Vec3 (x / l, y / l, z / l);
1362 Vec3<T>::normalizedExc () const throw (Iex::MathExc)
1367 throw NullVecExc ("Cannot normalize null vector.");
1369 return Vec3 (x / l, y / l, z / l);
1375 Vec3<T>::normalizedNonNull () const
1378 return Vec3 (x / l, y / l, z / l);
1382 //-----------------------------
1383 // Stream output implementation
1384 //-----------------------------
1388 operator << (std::ostream &s, const Vec2<T> &v)
1390 return s << '(' << v.x << ' ' << v.y << ')';
1395 operator << (std::ostream &s, const Vec3<T> &v)
1397 return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')';
1401 //-----------------------------------------
1402 // Implementation of reverse multiplication
1403 //-----------------------------------------
1407 operator * (T a, const Vec2<T> &v)
1409 return Vec2<T> (a * v.x, a * v.y);
1414 operator * (T a, const Vec3<T> &v)
1416 return Vec3<T> (a * v.x, a * v.y, a * v.z);
1420 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
1421 #pragma warning(default:4290)
1424 } // namespace Imath