HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ImathVec.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2004-2012, Industrial Light & Magic, a division of Lucas
4 // Digital Ltd. LLC
5 //
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
10 // met:
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
16 // distribution.
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.
20 //
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.
32 //
33 ///////////////////////////////////////////////////////////////////////////
34 
35 
36 
37 #ifndef INCLUDED_IMATHVEC_H
38 #define INCLUDED_IMATHVEC_H
39 
40 //----------------------------------------------------
41 //
42 // 2D, 3D and 4D point/vector class templates
43 //
44 //----------------------------------------------------
45 
46 #include "ImathExc.h"
47 #include "ImathLimits.h"
48 #include "ImathMath.h"
49 #include "ImathNamespace.h"
50 
51 #include <iostream>
52 
53 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
54 // suppress exception specification warnings
55 #pragma warning(push)
56 #pragma warning(disable:4290)
57 #endif
58 
59 
61 
62 template <class T> class Vec2;
63 template <class T> class Vec3;
64 template <class T> class Vec4;
65 
67 
68 
69 template <class T> class Vec2
70 {
71  public:
72 
73  //-------------------
74  // Access to elements
75  //-------------------
76 
77  T x, y;
78 
79  T & operator [] (int i);
80  const T & operator [] (int i) const;
81 
82 
83  //-------------
84  // Constructors
85  //-------------
86 
87  Vec2 (); // no initialization
88  explicit Vec2 (T a); // (a a)
89  Vec2 (T a, T b); // (a b)
90 
91 
92  //---------------------------------
93  // Copy constructors and assignment
94  //---------------------------------
95 
96  Vec2 (const Vec2 &v);
97  template <class S> Vec2 (const Vec2<S> &v);
98 
99  const Vec2 & operator = (const Vec2 &v);
100 
101 
102  //----------------------
103  // Compatibility with Sb
104  //----------------------
105 
106  template <class S>
107  void setValue (S a, S b);
108 
109  template <class S>
110  void setValue (const Vec2<S> &v);
111 
112  template <class S>
113  void getValue (S &a, S &b) const;
114 
115  template <class S>
116  void getValue (Vec2<S> &v) const;
117 
118  T * getValue ();
119  const T * getValue () const;
120 
121 
122  //---------
123  // Equality
124  //---------
125 
126  template <class S>
127  bool operator == (const Vec2<S> &v) const;
128 
129  template <class S>
130  bool operator != (const Vec2<S> &v) const;
131 
132 
133  //-----------------------------------------------------------------------
134  // Compare two vectors and test if they are "approximately equal":
135  //
136  // equalWithAbsError (v, e)
137  //
138  // Returns true if the coefficients of this and v are the same with
139  // an absolute error of no more than e, i.e., for all i
140  //
141  // abs (this[i] - v[i]) <= e
142  //
143  // equalWithRelError (v, e)
144  //
145  // Returns true if the coefficients of this and v are the same with
146  // a relative error of no more than e, i.e., for all i
147  //
148  // abs (this[i] - v[i]) <= e * abs (this[i])
149  //-----------------------------------------------------------------------
150 
151  bool equalWithAbsError (const Vec2<T> &v, T e) const;
152  bool equalWithRelError (const Vec2<T> &v, T e) const;
153 
154  //------------
155  // Dot product
156  //------------
157 
158  T dot (const Vec2 &v) const;
159  T operator ^ (const Vec2 &v) const;
160 
161 
162  //------------------------------------------------
163  // Right-handed cross product, i.e. z component of
164  // Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0)
165  //------------------------------------------------
166 
167  T cross (const Vec2 &v) const;
168  T operator % (const Vec2 &v) const;
169 
170 
171  //------------------------
172  // Component-wise addition
173  //------------------------
174 
175  const Vec2 & operator += (const Vec2 &v);
176  Vec2 operator + (const Vec2 &v) const;
177 
178 
179  //---------------------------
180  // Component-wise subtraction
181  //---------------------------
182 
183  const Vec2 & operator -= (const Vec2 &v);
184  Vec2 operator - (const Vec2 &v) const;
185 
186 
187  //------------------------------------
188  // Component-wise multiplication by -1
189  //------------------------------------
190 
191  Vec2 operator - () const;
192  const Vec2 & negate ();
193 
194 
195  //------------------------------
196  // Component-wise multiplication
197  //------------------------------
198 
199  const Vec2 & operator *= (const Vec2 &v);
200  const Vec2 & operator *= (T a);
201  Vec2 operator * (const Vec2 &v) const;
202  Vec2 operator * (T a) const;
203 
204 
205  //------------------------
206  // Component-wise division
207  //------------------------
208 
209  const Vec2 & operator /= (const Vec2 &v);
210  const Vec2 & operator /= (T a);
211  Vec2 operator / (const Vec2 &v) const;
212  Vec2 operator / (T a) const;
213 
214 
215  //----------------------------------------------------------------
216  // Length and normalization: If v.length() is 0.0, v.normalize()
217  // and v.normalized() produce a null vector; v.normalizeExc() and
218  // v.normalizedExc() throw a NullVecExc.
219  // v.normalizeNonNull() and v.normalizedNonNull() are slightly
220  // faster than the other normalization routines, but if v.length()
221  // is 0.0, the result is undefined.
222  //----------------------------------------------------------------
223 
224  T length () const;
225  T length2 () const;
226 
227  const Vec2 & normalize (); // modifies *this
228  const Vec2 & normalizeExc () throw (IEX_NAMESPACE::MathExc);
230 
231  Vec2<T> normalized () const; // does not modify *this
232  Vec2<T> normalizedExc () const throw (IEX_NAMESPACE::MathExc);
233  Vec2<T> normalizedNonNull () const;
234 
235 
236  //--------------------------------------------------------
237  // Number of dimensions, i.e. number of elements in a Vec2
238  //--------------------------------------------------------
239 
240  static unsigned int dimensions() {return 2;}
241 
242 
243  //-------------------------------------------------
244  // Limitations of type T (see also class limits<T>)
245  //-------------------------------------------------
246 
247  static T baseTypeMin() {return limits<T>::min();}
248  static T baseTypeMax() {return limits<T>::max();}
250  static T baseTypeEpsilon() {return limits<T>::epsilon();}
251 
252 
253  //--------------------------------------------------------------
254  // Base type -- in templates, which accept a parameter, V, which
255  // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can
256  // refer to T as V::BaseType
257  //--------------------------------------------------------------
258 
259  typedef T BaseType;
260 
261  private:
262 
263  T lengthTiny () const;
264 };
265 
266 
267 template <class T> class Vec3
268 {
269  public:
270 
271  //-------------------
272  // Access to elements
273  //-------------------
274 
275  T x, y, z;
276 
277  T & operator [] (int i);
278  const T & operator [] (int i) const;
279 
280 
281  //-------------
282  // Constructors
283  //-------------
284 
285  Vec3 (); // no initialization
286  explicit Vec3 (T a); // (a a a)
287  Vec3 (T a, T b, T c); // (a b c)
288 
289 
290  //---------------------------------
291  // Copy constructors and assignment
292  //---------------------------------
293 
294  Vec3 (const Vec3 &v);
295  template <class S> Vec3 (const Vec3<S> &v);
296 
297  const Vec3 & operator = (const Vec3 &v);
298 
299 
300  //---------------------------------------------------------
301  // Vec4 to Vec3 conversion, divides x, y and z by w:
302  //
303  // The one-argument conversion function divides by w even
304  // if w is zero. The result depends on how the environment
305  // handles floating-point exceptions.
306  //
307  // The two-argument version thows an InfPointExc exception
308  // if w is zero or if division by w would overflow.
309  //---------------------------------------------------------
310 
311  template <class S> explicit Vec3 (const Vec4<S> &v);
312  template <class S> explicit Vec3 (const Vec4<S> &v, InfException);
313 
314 
315  //----------------------
316  // Compatibility with Sb
317  //----------------------
318 
319  template <class S>
320  void setValue (S a, S b, S c);
321 
322  template <class S>
323  void setValue (const Vec3<S> &v);
324 
325  template <class S>
326  void getValue (S &a, S &b, S &c) const;
327 
328  template <class S>
329  void getValue (Vec3<S> &v) const;
330 
331  T * getValue();
332  const T * getValue() const;
333 
334 
335  //---------
336  // Equality
337  //---------
338 
339  template <class S>
340  bool operator == (const Vec3<S> &v) const;
341 
342  template <class S>
343  bool operator != (const Vec3<S> &v) const;
344 
345  //-----------------------------------------------------------------------
346  // Compare two vectors and test if they are "approximately equal":
347  //
348  // equalWithAbsError (v, e)
349  //
350  // Returns true if the coefficients of this and v are the same with
351  // an absolute error of no more than e, i.e., for all i
352  //
353  // abs (this[i] - v[i]) <= e
354  //
355  // equalWithRelError (v, e)
356  //
357  // Returns true if the coefficients of this and v are the same with
358  // a relative error of no more than e, i.e., for all i
359  //
360  // abs (this[i] - v[i]) <= e * abs (this[i])
361  //-----------------------------------------------------------------------
362 
363  bool equalWithAbsError (const Vec3<T> &v, T e) const;
364  bool equalWithRelError (const Vec3<T> &v, T e) const;
365 
366  //------------
367  // Dot product
368  //------------
369 
370  T dot (const Vec3 &v) const;
371  T operator ^ (const Vec3 &v) const;
372 
373 
374  //---------------------------
375  // Right-handed cross product
376  //---------------------------
377 
378  Vec3 cross (const Vec3 &v) const;
379  const Vec3 & operator %= (const Vec3 &v);
380  Vec3 operator % (const Vec3 &v) const;
381 
382 
383  //------------------------
384  // Component-wise addition
385  //------------------------
386 
387  const Vec3 & operator += (const Vec3 &v);
388  Vec3 operator + (const Vec3 &v) const;
389 
390 
391  //---------------------------
392  // Component-wise subtraction
393  //---------------------------
394 
395  const Vec3 & operator -= (const Vec3 &v);
396  Vec3 operator - (const Vec3 &v) const;
397 
398 
399  //------------------------------------
400  // Component-wise multiplication by -1
401  //------------------------------------
402 
403  Vec3 operator - () const;
404  const Vec3 & negate ();
405 
406 
407  //------------------------------
408  // Component-wise multiplication
409  //------------------------------
410 
411  const Vec3 & operator *= (const Vec3 &v);
412  const Vec3 & operator *= (T a);
413  Vec3 operator * (const Vec3 &v) const;
414  Vec3 operator * (T a) const;
415 
416 
417  //------------------------
418  // Component-wise division
419  //------------------------
420 
421  const Vec3 & operator /= (const Vec3 &v);
422  const Vec3 & operator /= (T a);
423  Vec3 operator / (const Vec3 &v) const;
424  Vec3 operator / (T a) const;
425 
426 
427  //----------------------------------------------------------------
428  // Length and normalization: If v.length() is 0.0, v.normalize()
429  // and v.normalized() produce a null vector; v.normalizeExc() and
430  // v.normalizedExc() throw a NullVecExc.
431  // v.normalizeNonNull() and v.normalizedNonNull() are slightly
432  // faster than the other normalization routines, but if v.length()
433  // is 0.0, the result is undefined.
434  //----------------------------------------------------------------
435 
436  T length () const;
437  T length2 () const;
438 
439  const Vec3 & normalize (); // modifies *this
440  const Vec3 & normalizeExc () throw (IEX_NAMESPACE::MathExc);
442 
443  Vec3<T> normalized () const; // does not modify *this
444  Vec3<T> normalizedExc () const throw (IEX_NAMESPACE::MathExc);
445  Vec3<T> normalizedNonNull () const;
446 
447 
448  //--------------------------------------------------------
449  // Number of dimensions, i.e. number of elements in a Vec3
450  //--------------------------------------------------------
451 
452  static unsigned int dimensions() {return 3;}
453 
454 
455  //-------------------------------------------------
456  // Limitations of type T (see also class limits<T>)
457  //-------------------------------------------------
458 
459  static T baseTypeMin() {return limits<T>::min();}
460  static T baseTypeMax() {return limits<T>::max();}
462  static T baseTypeEpsilon() {return limits<T>::epsilon();}
463 
464 
465  //--------------------------------------------------------------
466  // Base type -- in templates, which accept a parameter, V, which
467  // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can
468  // refer to T as V::BaseType
469  //--------------------------------------------------------------
470 
471  typedef T BaseType;
472 
473  private:
474 
475  T lengthTiny () const;
476 };
477 
478 
479 
480 template <class T> class Vec4
481 {
482  public:
483 
484  //-------------------
485  // Access to elements
486  //-------------------
487 
488  T x, y, z, w;
489 
490  T & operator [] (int i);
491  const T & operator [] (int i) const;
492 
493 
494  //-------------
495  // Constructors
496  //-------------
497 
498  Vec4 (); // no initialization
499  explicit Vec4 (T a); // (a a a a)
500  Vec4 (T a, T b, T c, T d); // (a b c d)
501 
502 
503  //---------------------------------
504  // Copy constructors and assignment
505  //---------------------------------
506 
507  Vec4 (const Vec4 &v);
508  template <class S> Vec4 (const Vec4<S> &v);
509 
510  const Vec4 & operator = (const Vec4 &v);
511 
512 
513  //-------------------------------------
514  // Vec3 to Vec4 conversion, sets w to 1
515  //-------------------------------------
516 
517  template <class S> explicit Vec4 (const Vec3<S> &v);
518 
519 
520  //---------
521  // Equality
522  //---------
523 
524  template <class S>
525  bool operator == (const Vec4<S> &v) const;
526 
527  template <class S>
528  bool operator != (const Vec4<S> &v) const;
529 
530 
531  //-----------------------------------------------------------------------
532  // Compare two vectors and test if they are "approximately equal":
533  //
534  // equalWithAbsError (v, e)
535  //
536  // Returns true if the coefficients of this and v are the same with
537  // an absolute error of no more than e, i.e., for all i
538  //
539  // abs (this[i] - v[i]) <= e
540  //
541  // equalWithRelError (v, e)
542  //
543  // Returns true if the coefficients of this and v are the same with
544  // a relative error of no more than e, i.e., for all i
545  //
546  // abs (this[i] - v[i]) <= e * abs (this[i])
547  //-----------------------------------------------------------------------
548 
549  bool equalWithAbsError (const Vec4<T> &v, T e) const;
550  bool equalWithRelError (const Vec4<T> &v, T e) const;
551 
552 
553  //------------
554  // Dot product
555  //------------
556 
557  T dot (const Vec4 &v) const;
558  T operator ^ (const Vec4 &v) const;
559 
560 
561  //-----------------------------------
562  // Cross product is not defined in 4D
563  //-----------------------------------
564 
565  //------------------------
566  // Component-wise addition
567  //------------------------
568 
569  const Vec4 & operator += (const Vec4 &v);
570  Vec4 operator + (const Vec4 &v) const;
571 
572 
573  //---------------------------
574  // Component-wise subtraction
575  //---------------------------
576 
577  const Vec4 & operator -= (const Vec4 &v);
578  Vec4 operator - (const Vec4 &v) const;
579 
580 
581  //------------------------------------
582  // Component-wise multiplication by -1
583  //------------------------------------
584 
585  Vec4 operator - () const;
586  const Vec4 & negate ();
587 
588 
589  //------------------------------
590  // Component-wise multiplication
591  //------------------------------
592 
593  const Vec4 & operator *= (const Vec4 &v);
594  const Vec4 & operator *= (T a);
595  Vec4 operator * (const Vec4 &v) const;
596  Vec4 operator * (T a) const;
597 
598 
599  //------------------------
600  // Component-wise division
601  //------------------------
602 
603  const Vec4 & operator /= (const Vec4 &v);
604  const Vec4 & operator /= (T a);
605  Vec4 operator / (const Vec4 &v) const;
606  Vec4 operator / (T a) const;
607 
608 
609  //----------------------------------------------------------------
610  // Length and normalization: If v.length() is 0.0, v.normalize()
611  // and v.normalized() produce a null vector; v.normalizeExc() and
612  // v.normalizedExc() throw a NullVecExc.
613  // v.normalizeNonNull() and v.normalizedNonNull() are slightly
614  // faster than the other normalization routines, but if v.length()
615  // is 0.0, the result is undefined.
616  //----------------------------------------------------------------
617 
618  T length () const;
619  T length2 () const;
620 
621  const Vec4 & normalize (); // modifies *this
622  const Vec4 & normalizeExc () throw (IEX_NAMESPACE::MathExc);
624 
625  Vec4<T> normalized () const; // does not modify *this
626  Vec4<T> normalizedExc () const throw (IEX_NAMESPACE::MathExc);
627  Vec4<T> normalizedNonNull () const;
628 
629 
630  //--------------------------------------------------------
631  // Number of dimensions, i.e. number of elements in a Vec4
632  //--------------------------------------------------------
633 
634  static unsigned int dimensions() {return 4;}
635 
636 
637  //-------------------------------------------------
638  // Limitations of type T (see also class limits<T>)
639  //-------------------------------------------------
640 
641  static T baseTypeMin() {return limits<T>::min();}
642  static T baseTypeMax() {return limits<T>::max();}
644  static T baseTypeEpsilon() {return limits<T>::epsilon();}
645 
646 
647  //--------------------------------------------------------------
648  // Base type -- in templates, which accept a parameter, V, which
649  // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can
650  // refer to T as V::BaseType
651  //--------------------------------------------------------------
652 
653  typedef T BaseType;
654 
655  private:
656 
657  T lengthTiny () const;
658 };
659 
660 
661 //--------------
662 // Stream output
663 //--------------
664 
665 template <class T>
666 std::ostream & operator << (std::ostream &s, const Vec2<T> &v);
667 
668 template <class T>
669 std::ostream & operator << (std::ostream &s, const Vec3<T> &v);
670 
671 template <class T>
672 std::ostream & operator << (std::ostream &s, const Vec4<T> &v);
673 
674 //----------------------------------------------------
675 // Reverse multiplication: S * Vec2<T> and S * Vec3<T>
676 //----------------------------------------------------
677 
678 template <class T> Vec2<T> operator * (T a, const Vec2<T> &v);
679 template <class T> Vec3<T> operator * (T a, const Vec3<T> &v);
680 template <class T> Vec4<T> operator * (T a, const Vec4<T> &v);
681 
682 
683 //-------------------------
684 // Typedefs for convenience
685 //-------------------------
686 
688 typedef Vec2 <int> V2i;
692 typedef Vec3 <int> V3i;
696 typedef Vec4 <int> V4i;
699 
700 
701 //-------------------------------------------
702 // Specializations for VecN<short>, VecN<int>
703 //-------------------------------------------
704 
705 // Vec2<short>
706 
707 template <> short
708 Vec2<short>::length () const;
709 
710 template <> const Vec2<short> &
712 
713 template <> const Vec2<short> &
714 Vec2<short>::normalizeExc () throw (IEX_NAMESPACE::MathExc);
715 
716 template <> const Vec2<short> &
717 Vec2<short>::normalizeNonNull ();
718 
719 template <> Vec2<short>
720 Vec2<short>::normalized () const;
721 
722 template <> Vec2<short>
723 Vec2<short>::normalizedExc () const throw (IEX_NAMESPACE::MathExc);
724 
725 template <> Vec2<short>
726 Vec2<short>::normalizedNonNull () const;
727 
728 
729 // Vec2<int>
730 
731 template <> int
732 Vec2<int>::length () const;
733 
734 template <> const Vec2<int> &
735 Vec2<int>::normalize ();
736 
737 template <> const Vec2<int> &
738 Vec2<int>::normalizeExc () throw (IEX_NAMESPACE::MathExc);
739 
740 template <> const Vec2<int> &
741 Vec2<int>::normalizeNonNull ();
742 
743 template <> Vec2<int>
744 Vec2<int>::normalized () const;
745 
746 template <> Vec2<int>
747 Vec2<int>::normalizedExc () const throw (IEX_NAMESPACE::MathExc);
748 
749 template <> Vec2<int>
750 Vec2<int>::normalizedNonNull () const;
751 
752 
753 // Vec3<short>
754 
755 template <> short
756 Vec3<short>::length () const;
757 
758 template <> const Vec3<short> &
759 Vec3<short>::normalize ();
760 
761 template <> const Vec3<short> &
762 Vec3<short>::normalizeExc () throw (IEX_NAMESPACE::MathExc);
763 
764 template <> const Vec3<short> &
765 Vec3<short>::normalizeNonNull ();
766 
767 template <> Vec3<short>
768 Vec3<short>::normalized () const;
769 
770 template <> Vec3<short>
771 Vec3<short>::normalizedExc () const throw (IEX_NAMESPACE::MathExc);
772 
773 template <> Vec3<short>
774 Vec3<short>::normalizedNonNull () const;
775 
776 
777 // Vec3<int>
778 
779 template <> int
780 Vec3<int>::length () const;
781 
782 template <> const Vec3<int> &
783 Vec3<int>::normalize ();
784 
785 template <> const Vec3<int> &
786 Vec3<int>::normalizeExc () throw (IEX_NAMESPACE::MathExc);
787 
788 template <> const Vec3<int> &
789 Vec3<int>::normalizeNonNull ();
790 
791 template <> Vec3<int>
792 Vec3<int>::normalized () const;
793 
794 template <> Vec3<int>
795 Vec3<int>::normalizedExc () const throw (IEX_NAMESPACE::MathExc);
796 
797 template <> Vec3<int>
798 Vec3<int>::normalizedNonNull () const;
799 
800 // Vec4<short>
801 
802 template <> short
803 Vec4<short>::length () const;
804 
805 template <> const Vec4<short> &
806 Vec4<short>::normalize ();
807 
808 template <> const Vec4<short> &
809 Vec4<short>::normalizeExc () throw (IEX_NAMESPACE::MathExc);
810 
811 template <> const Vec4<short> &
812 Vec4<short>::normalizeNonNull ();
813 
814 template <> Vec4<short>
815 Vec4<short>::normalized () const;
816 
817 template <> Vec4<short>
818 Vec4<short>::normalizedExc () const throw (IEX_NAMESPACE::MathExc);
819 
820 template <> Vec4<short>
821 Vec4<short>::normalizedNonNull () const;
822 
823 
824 // Vec4<int>
825 
826 template <> int
827 Vec4<int>::length () const;
828 
829 template <> const Vec4<int> &
830 Vec4<int>::normalize ();
831 
832 template <> const Vec4<int> &
833 Vec4<int>::normalizeExc () throw (IEX_NAMESPACE::MathExc);
834 
835 template <> const Vec4<int> &
836 Vec4<int>::normalizeNonNull ();
837 
838 template <> Vec4<int>
839 Vec4<int>::normalized () const;
840 
841 template <> Vec4<int>
842 Vec4<int>::normalizedExc () const throw (IEX_NAMESPACE::MathExc);
843 
844 template <> Vec4<int>
845 Vec4<int>::normalizedNonNull () const;
846 
847 
848 //------------------------
849 // Implementation of Vec2:
850 //------------------------
851 
852 template <class T>
853 inline T &
854 Vec2<T>::operator [] (int i)
855 {
856  return (&x)[i];
857 }
858 
859 template <class T>
860 inline const T &
862 {
863  return (&x)[i];
864 }
865 
866 template <class T>
867 inline
869 {
870  // empty
871 }
872 
873 template <class T>
874 inline
876 {
877  x = y = a;
878 }
879 
880 template <class T>
881 inline
883 {
884  x = a;
885  y = b;
886 }
887 
888 template <class T>
889 inline
891 {
892  x = v.x;
893  y = v.y;
894 }
895 
896 template <class T>
897 template <class S>
898 inline
900 {
901  x = T (v.x);
902  y = T (v.y);
903 }
904 
905 template <class T>
906 inline const Vec2<T> &
908 {
909  x = v.x;
910  y = v.y;
911  return *this;
912 }
913 
914 template <class T>
915 template <class S>
916 inline void
918 {
919  x = T (a);
920  y = T (b);
921 }
922 
923 template <class T>
924 template <class S>
925 inline void
927 {
928  x = T (v.x);
929  y = T (v.y);
930 }
931 
932 template <class T>
933 template <class S>
934 inline void
935 Vec2<T>::getValue (S &a, S &b) const
936 {
937  a = S (x);
938  b = S (y);
939 }
940 
941 template <class T>
942 template <class S>
943 inline void
945 {
946  v.x = S (x);
947  v.y = S (y);
948 }
949 
950 template <class T>
951 inline T *
953 {
954  return (T *) &x;
955 }
956 
957 template <class T>
958 inline const T *
960 {
961  return (const T *) &x;
962 }
963 
964 template <class T>
965 template <class S>
966 inline bool
968 {
969  return x == v.x && y == v.y;
970 }
971 
972 template <class T>
973 template <class S>
974 inline bool
976 {
977  return x != v.x || y != v.y;
978 }
979 
980 template <class T>
981 bool
983 {
984  for (int i = 0; i < 2; i++)
985  if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], v[i], e))
986  return false;
987 
988  return true;
989 }
990 
991 template <class T>
992 bool
994 {
995  for (int i = 0; i < 2; i++)
996  if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], v[i], e))
997  return false;
998 
999  return true;
1000 }
1001 
1002 template <class T>
1003 inline T
1004 Vec2<T>::dot (const Vec2 &v) const
1005 {
1006  return x * v.x + y * v.y;
1007 }
1008 
1009 template <class T>
1010 inline T
1012 {
1013  return dot (v);
1014 }
1015 
1016 template <class T>
1017 inline T
1018 Vec2<T>::cross (const Vec2 &v) const
1019 {
1020  return x * v.y - y * v.x;
1021 
1022 }
1023 
1024 template <class T>
1025 inline T
1027 {
1028  return x * v.y - y * v.x;
1029 }
1030 
1031 template <class T>
1032 inline const Vec2<T> &
1034 {
1035  x += v.x;
1036  y += v.y;
1037  return *this;
1038 }
1039 
1040 template <class T>
1041 inline Vec2<T>
1043 {
1044  return Vec2 (x + v.x, y + v.y);
1045 }
1046 
1047 template <class T>
1048 inline const Vec2<T> &
1050 {
1051  x -= v.x;
1052  y -= v.y;
1053  return *this;
1054 }
1055 
1056 template <class T>
1057 inline Vec2<T>
1059 {
1060  return Vec2 (x - v.x, y - v.y);
1061 }
1062 
1063 template <class T>
1064 inline Vec2<T>
1066 {
1067  return Vec2 (-x, -y);
1068 }
1069 
1070 template <class T>
1071 inline const Vec2<T> &
1073 {
1074  x = -x;
1075  y = -y;
1076  return *this;
1077 }
1078 
1079 template <class T>
1080 inline const Vec2<T> &
1082 {
1083  x *= v.x;
1084  y *= v.y;
1085  return *this;
1086 }
1087 
1088 template <class T>
1089 inline const Vec2<T> &
1091 {
1092  x *= a;
1093  y *= a;
1094  return *this;
1095 }
1096 
1097 template <class T>
1098 inline Vec2<T>
1100 {
1101  return Vec2 (x * v.x, y * v.y);
1102 }
1103 
1104 template <class T>
1105 inline Vec2<T>
1107 {
1108  return Vec2 (x * a, y * a);
1109 }
1110 
1111 template <class T>
1112 inline const Vec2<T> &
1114 {
1115  x /= v.x;
1116  y /= v.y;
1117  return *this;
1118 }
1119 
1120 template <class T>
1121 inline const Vec2<T> &
1123 {
1124  x /= a;
1125  y /= a;
1126  return *this;
1127 }
1128 
1129 template <class T>
1130 inline Vec2<T>
1132 {
1133  return Vec2 (x / v.x, y / v.y);
1134 }
1135 
1136 template <class T>
1137 inline Vec2<T>
1139 {
1140  return Vec2 (x / a, y / a);
1141 }
1142 
1143 template <class T>
1144 T
1145 Vec2<T>::lengthTiny () const
1146 {
1147  T absX = (x >= T (0))? x: -x;
1148  T absY = (y >= T (0))? y: -y;
1149 
1150  T max = absX;
1151 
1152  if (max < absY)
1153  max = absY;
1154 
1155  if (max == T (0))
1156  return T (0);
1157 
1158  //
1159  // Do not replace the divisions by max with multiplications by 1/max.
1160  // Computing 1/max can overflow but the divisions below will always
1161  // produce results less than or equal to 1.
1162  //
1163 
1164  absX /= max;
1165  absY /= max;
1166 
1167  return max * Math<T>::sqrt (absX * absX + absY * absY);
1168 }
1169 
1170 template <class T>
1171 inline T
1173 {
1174  T length2 = dot (*this);
1175 
1176  if (length2 < T (2) * limits<T>::smallest())
1177  return lengthTiny();
1178 
1179  return Math<T>::sqrt (length2);
1180 }
1181 
1182 template <class T>
1183 inline T
1185 {
1186  return dot (*this);
1187 }
1188 
1189 template <class T>
1190 const Vec2<T> &
1192 {
1193  T l = length();
1194 
1195  if (l != T (0))
1196  {
1197  //
1198  // Do not replace the divisions by l with multiplications by 1/l.
1199  // Computing 1/l can overflow but the divisions below will always
1200  // produce results less than or equal to 1.
1201  //
1202 
1203  x /= l;
1204  y /= l;
1205  }
1206 
1207  return *this;
1208 }
1209 
1210 template <class T>
1211 const Vec2<T> &
1213 {
1214  T l = length();
1215 
1216  if (l == T (0))
1217  throw NullVecExc ("Cannot normalize null vector.");
1218 
1219  x /= l;
1220  y /= l;
1221  return *this;
1222 }
1223 
1224 template <class T>
1225 inline
1226 const Vec2<T> &
1228 {
1229  T l = length();
1230  x /= l;
1231  y /= l;
1232  return *this;
1233 }
1234 
1235 template <class T>
1236 Vec2<T>
1238 {
1239  T l = length();
1240 
1241  if (l == T (0))
1242  return Vec2 (T (0));
1243 
1244  return Vec2 (x / l, y / l);
1245 }
1246 
1247 template <class T>
1248 Vec2<T>
1249 Vec2<T>::normalizedExc () const throw (IEX_NAMESPACE::MathExc)
1250 {
1251  T l = length();
1252 
1253  if (l == T (0))
1254  throw NullVecExc ("Cannot normalize null vector.");
1255 
1256  return Vec2 (x / l, y / l);
1257 }
1258 
1259 template <class T>
1260 inline
1261 Vec2<T>
1263 {
1264  T l = length();
1265  return Vec2 (x / l, y / l);
1266 }
1267 
1268 
1269 //-----------------------
1270 // Implementation of Vec3
1271 //-----------------------
1272 
1273 template <class T>
1274 inline T &
1276 {
1277  return (&x)[i];
1278 }
1279 
1280 template <class T>
1281 inline const T &
1283 {
1284  return (&x)[i];
1285 }
1286 
1287 template <class T>
1288 inline
1290 {
1291  // empty
1292 }
1293 
1294 template <class T>
1295 inline
1297 {
1298  x = y = z = a;
1299 }
1300 
1301 template <class T>
1302 inline
1303 Vec3<T>::Vec3 (T a, T b, T c)
1304 {
1305  x = a;
1306  y = b;
1307  z = c;
1308 }
1309 
1310 template <class T>
1311 inline
1313 {
1314  x = v.x;
1315  y = v.y;
1316  z = v.z;
1317 }
1318 
1319 template <class T>
1320 template <class S>
1321 inline
1323 {
1324  x = T (v.x);
1325  y = T (v.y);
1326  z = T (v.z);
1327 }
1328 
1329 template <class T>
1330 inline const Vec3<T> &
1332 {
1333  x = v.x;
1334  y = v.y;
1335  z = v.z;
1336  return *this;
1337 }
1338 
1339 template <class T>
1340 template <class S>
1341 inline
1343 {
1344  x = T (v.x / v.w);
1345  y = T (v.y / v.w);
1346  z = T (v.z / v.w);
1347 }
1348 
1349 template <class T>
1350 template <class S>
1352 {
1353  T vx = T (v.x);
1354  T vy = T (v.y);
1355  T vz = T (v.z);
1356  T vw = T (v.w);
1357 
1358  T absW = (vw >= T (0))? vw: -vw;
1359 
1360  if (absW < 1)
1361  {
1362  T m = baseTypeMax() * absW;
1363 
1364  if (vx <= -m || vx >= m || vy <= -m || vy >= m || vz <= -m || vz >= m)
1365  throw InfPointExc ("Cannot normalize point at infinity.");
1366  }
1367 
1368  x = vx / vw;
1369  y = vy / vw;
1370  z = vz / vw;
1371 }
1372 
1373 template <class T>
1374 template <class S>
1375 inline void
1376 Vec3<T>::setValue (S a, S b, S c)
1377 {
1378  x = T (a);
1379  y = T (b);
1380  z = T (c);
1381 }
1382 
1383 template <class T>
1384 template <class S>
1385 inline void
1387 {
1388  x = T (v.x);
1389  y = T (v.y);
1390  z = T (v.z);
1391 }
1392 
1393 template <class T>
1394 template <class S>
1395 inline void
1396 Vec3<T>::getValue (S &a, S &b, S &c) const
1397 {
1398  a = S (x);
1399  b = S (y);
1400  c = S (z);
1401 }
1402 
1403 template <class T>
1404 template <class S>
1405 inline void
1407 {
1408  v.x = S (x);
1409  v.y = S (y);
1410  v.z = S (z);
1411 }
1412 
1413 template <class T>
1414 inline T *
1416 {
1417  return (T *) &x;
1418 }
1419 
1420 template <class T>
1421 inline const T *
1423 {
1424  return (const T *) &x;
1425 }
1426 
1427 template <class T>
1428 template <class S>
1429 inline bool
1431 {
1432  return x == v.x && y == v.y && z == v.z;
1433 }
1434 
1435 template <class T>
1436 template <class S>
1437 inline bool
1439 {
1440  return x != v.x || y != v.y || z != v.z;
1441 }
1442 
1443 template <class T>
1444 bool
1446 {
1447  for (int i = 0; i < 3; i++)
1448  if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], v[i], e))
1449  return false;
1450 
1451  return true;
1452 }
1453 
1454 template <class T>
1455 bool
1457 {
1458  for (int i = 0; i < 3; i++)
1459  if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], v[i], e))
1460  return false;
1461 
1462  return true;
1463 }
1464 
1465 template <class T>
1466 inline T
1467 Vec3<T>::dot (const Vec3 &v) const
1468 {
1469  return x * v.x + y * v.y + z * v.z;
1470 }
1471 
1472 template <class T>
1473 inline T
1475 {
1476  return dot (v);
1477 }
1478 
1479 template <class T>
1480 inline Vec3<T>
1481 Vec3<T>::cross (const Vec3 &v) const
1482 {
1483  return Vec3 (y * v.z - z * v.y,
1484  z * v.x - x * v.z,
1485  x * v.y - y * v.x);
1486 }
1487 
1488 template <class T>
1489 inline const Vec3<T> &
1491 {
1492  T a = y * v.z - z * v.y;
1493  T b = z * v.x - x * v.z;
1494  T c = x * v.y - y * v.x;
1495  x = a;
1496  y = b;
1497  z = c;
1498  return *this;
1499 }
1500 
1501 template <class T>
1502 inline Vec3<T>
1504 {
1505  return Vec3 (y * v.z - z * v.y,
1506  z * v.x - x * v.z,
1507  x * v.y - y * v.x);
1508 }
1509 
1510 template <class T>
1511 inline const Vec3<T> &
1513 {
1514  x += v.x;
1515  y += v.y;
1516  z += v.z;
1517  return *this;
1518 }
1519 
1520 template <class T>
1521 inline Vec3<T>
1523 {
1524  return Vec3 (x + v.x, y + v.y, z + v.z);
1525 }
1526 
1527 template <class T>
1528 inline const Vec3<T> &
1530 {
1531  x -= v.x;
1532  y -= v.y;
1533  z -= v.z;
1534  return *this;
1535 }
1536 
1537 template <class T>
1538 inline Vec3<T>
1540 {
1541  return Vec3 (x - v.x, y - v.y, z - v.z);
1542 }
1543 
1544 template <class T>
1545 inline Vec3<T>
1547 {
1548  return Vec3 (-x, -y, -z);
1549 }
1550 
1551 template <class T>
1552 inline const Vec3<T> &
1554 {
1555  x = -x;
1556  y = -y;
1557  z = -z;
1558  return *this;
1559 }
1560 
1561 template <class T>
1562 inline const Vec3<T> &
1564 {
1565  x *= v.x;
1566  y *= v.y;
1567  z *= v.z;
1568  return *this;
1569 }
1570 
1571 template <class T>
1572 inline const Vec3<T> &
1574 {
1575  x *= a;
1576  y *= a;
1577  z *= a;
1578  return *this;
1579 }
1580 
1581 template <class T>
1582 inline Vec3<T>
1584 {
1585  return Vec3 (x * v.x, y * v.y, z * v.z);
1586 }
1587 
1588 template <class T>
1589 inline Vec3<T>
1591 {
1592  return Vec3 (x * a, y * a, z * a);
1593 }
1594 
1595 template <class T>
1596 inline const Vec3<T> &
1598 {
1599  x /= v.x;
1600  y /= v.y;
1601  z /= v.z;
1602  return *this;
1603 }
1604 
1605 template <class T>
1606 inline const Vec3<T> &
1608 {
1609  x /= a;
1610  y /= a;
1611  z /= a;
1612  return *this;
1613 }
1614 
1615 template <class T>
1616 inline Vec3<T>
1618 {
1619  return Vec3 (x / v.x, y / v.y, z / v.z);
1620 }
1621 
1622 template <class T>
1623 inline Vec3<T>
1625 {
1626  return Vec3 (x / a, y / a, z / a);
1627 }
1628 
1629 template <class T>
1630 T
1631 Vec3<T>::lengthTiny () const
1632 {
1633  T absX = (x >= T (0))? x: -x;
1634  T absY = (y >= T (0))? y: -y;
1635  T absZ = (z >= T (0))? z: -z;
1636 
1637  T max = absX;
1638 
1639  if (max < absY)
1640  max = absY;
1641 
1642  if (max < absZ)
1643  max = absZ;
1644 
1645  if (max == T (0))
1646  return T (0);
1647 
1648  //
1649  // Do not replace the divisions by max with multiplications by 1/max.
1650  // Computing 1/max can overflow but the divisions below will always
1651  // produce results less than or equal to 1.
1652  //
1653 
1654  absX /= max;
1655  absY /= max;
1656  absZ /= max;
1657 
1658  return max * Math<T>::sqrt (absX * absX + absY * absY + absZ * absZ);
1659 }
1660 
1661 template <class T>
1662 inline T
1664 {
1665  T length2 = dot (*this);
1666 
1667  if (length2 < T (2) * limits<T>::smallest())
1668  return lengthTiny();
1669 
1670  return Math<T>::sqrt (length2);
1671 }
1672 
1673 template <class T>
1674 inline T
1676 {
1677  return dot (*this);
1678 }
1679 
1680 template <class T>
1681 const Vec3<T> &
1683 {
1684  T l = length();
1685 
1686  if (l != T (0))
1687  {
1688  //
1689  // Do not replace the divisions by l with multiplications by 1/l.
1690  // Computing 1/l can overflow but the divisions below will always
1691  // produce results less than or equal to 1.
1692  //
1693 
1694  x /= l;
1695  y /= l;
1696  z /= l;
1697  }
1698 
1699  return *this;
1700 }
1701 
1702 template <class T>
1703 const Vec3<T> &
1705 {
1706  T l = length();
1707 
1708  if (l == T (0))
1709  throw NullVecExc ("Cannot normalize null vector.");
1710 
1711  x /= l;
1712  y /= l;
1713  z /= l;
1714  return *this;
1715 }
1716 
1717 template <class T>
1718 inline
1719 const Vec3<T> &
1721 {
1722  T l = length();
1723  x /= l;
1724  y /= l;
1725  z /= l;
1726  return *this;
1727 }
1728 
1729 template <class T>
1730 Vec3<T>
1732 {
1733  T l = length();
1734 
1735  if (l == T (0))
1736  return Vec3 (T (0));
1737 
1738  return Vec3 (x / l, y / l, z / l);
1739 }
1740 
1741 template <class T>
1742 Vec3<T>
1743 Vec3<T>::normalizedExc () const throw (IEX_NAMESPACE::MathExc)
1744 {
1745  T l = length();
1746 
1747  if (l == T (0))
1748  throw NullVecExc ("Cannot normalize null vector.");
1749 
1750  return Vec3 (x / l, y / l, z / l);
1751 }
1752 
1753 template <class T>
1754 inline
1755 Vec3<T>
1757 {
1758  T l = length();
1759  return Vec3 (x / l, y / l, z / l);
1760 }
1761 
1762 
1763 //-----------------------
1764 // Implementation of Vec4
1765 //-----------------------
1766 
1767 template <class T>
1768 inline T &
1770 {
1771  return (&x)[i];
1772 }
1773 
1774 template <class T>
1775 inline const T &
1777 {
1778  return (&x)[i];
1779 }
1780 
1781 template <class T>
1782 inline
1784 {
1785  // empty
1786 }
1787 
1788 template <class T>
1789 inline
1791 {
1792  x = y = z = w = a;
1793 }
1794 
1795 template <class T>
1796 inline
1797 Vec4<T>::Vec4 (T a, T b, T c, T d)
1798 {
1799  x = a;
1800  y = b;
1801  z = c;
1802  w = d;
1803 }
1804 
1805 template <class T>
1806 inline
1808 {
1809  x = v.x;
1810  y = v.y;
1811  z = v.z;
1812  w = v.w;
1813 }
1814 
1815 template <class T>
1816 template <class S>
1817 inline
1819 {
1820  x = T (v.x);
1821  y = T (v.y);
1822  z = T (v.z);
1823  w = T (v.w);
1824 }
1825 
1826 template <class T>
1827 inline const Vec4<T> &
1829 {
1830  x = v.x;
1831  y = v.y;
1832  z = v.z;
1833  w = v.w;
1834  return *this;
1835 }
1836 
1837 template <class T>
1838 template <class S>
1839 inline
1841 {
1842  x = T (v.x);
1843  y = T (v.y);
1844  z = T (v.z);
1845  w = T (1);
1846 }
1847 
1848 template <class T>
1849 template <class S>
1850 inline bool
1852 {
1853  return x == v.x && y == v.y && z == v.z && w == v.w;
1854 }
1855 
1856 template <class T>
1857 template <class S>
1858 inline bool
1860 {
1861  return x != v.x || y != v.y || z != v.z || w != v.w;
1862 }
1863 
1864 template <class T>
1865 bool
1867 {
1868  for (int i = 0; i < 4; i++)
1869  if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], v[i], e))
1870  return false;
1871 
1872  return true;
1873 }
1874 
1875 template <class T>
1876 bool
1878 {
1879  for (int i = 0; i < 4; i++)
1880  if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], v[i], e))
1881  return false;
1882 
1883  return true;
1884 }
1885 
1886 template <class T>
1887 inline T
1888 Vec4<T>::dot (const Vec4 &v) const
1889 {
1890  return x * v.x + y * v.y + z * v.z + w * v.w;
1891 }
1892 
1893 template <class T>
1894 inline T
1896 {
1897  return dot (v);
1898 }
1899 
1900 
1901 template <class T>
1902 inline const Vec4<T> &
1904 {
1905  x += v.x;
1906  y += v.y;
1907  z += v.z;
1908  w += v.w;
1909  return *this;
1910 }
1911 
1912 template <class T>
1913 inline Vec4<T>
1915 {
1916  return Vec4 (x + v.x, y + v.y, z + v.z, w + v.w);
1917 }
1918 
1919 template <class T>
1920 inline const Vec4<T> &
1922 {
1923  x -= v.x;
1924  y -= v.y;
1925  z -= v.z;
1926  w -= v.w;
1927  return *this;
1928 }
1929 
1930 template <class T>
1931 inline Vec4<T>
1933 {
1934  return Vec4 (x - v.x, y - v.y, z - v.z, w - v.w);
1935 }
1936 
1937 template <class T>
1938 inline Vec4<T>
1940 {
1941  return Vec4 (-x, -y, -z, -w);
1942 }
1943 
1944 template <class T>
1945 inline const Vec4<T> &
1947 {
1948  x = -x;
1949  y = -y;
1950  z = -z;
1951  w = -w;
1952  return *this;
1953 }
1954 
1955 template <class T>
1956 inline const Vec4<T> &
1958 {
1959  x *= v.x;
1960  y *= v.y;
1961  z *= v.z;
1962  w *= v.w;
1963  return *this;
1964 }
1965 
1966 template <class T>
1967 inline const Vec4<T> &
1969 {
1970  x *= a;
1971  y *= a;
1972  z *= a;
1973  w *= a;
1974  return *this;
1975 }
1976 
1977 template <class T>
1978 inline Vec4<T>
1980 {
1981  return Vec4 (x * v.x, y * v.y, z * v.z, w * v.w);
1982 }
1983 
1984 template <class T>
1985 inline Vec4<T>
1987 {
1988  return Vec4 (x * a, y * a, z * a, w * a);
1989 }
1990 
1991 template <class T>
1992 inline const Vec4<T> &
1994 {
1995  x /= v.x;
1996  y /= v.y;
1997  z /= v.z;
1998  w /= v.w;
1999  return *this;
2000 }
2001 
2002 template <class T>
2003 inline const Vec4<T> &
2005 {
2006  x /= a;
2007  y /= a;
2008  z /= a;
2009  w /= a;
2010  return *this;
2011 }
2012 
2013 template <class T>
2014 inline Vec4<T>
2016 {
2017  return Vec4 (x / v.x, y / v.y, z / v.z, w / v.w);
2018 }
2019 
2020 template <class T>
2021 inline Vec4<T>
2023 {
2024  return Vec4 (x / a, y / a, z / a, w / a);
2025 }
2026 
2027 template <class T>
2028 T
2029 Vec4<T>::lengthTiny () const
2030 {
2031  T absX = (x >= T (0))? x: -x;
2032  T absY = (y >= T (0))? y: -y;
2033  T absZ = (z >= T (0))? z: -z;
2034  T absW = (w >= T (0))? w: -w;
2035 
2036  T max = absX;
2037 
2038  if (max < absY)
2039  max = absY;
2040 
2041  if (max < absZ)
2042  max = absZ;
2043 
2044  if (max < absW)
2045  max = absW;
2046 
2047  if (max == T (0))
2048  return T (0);
2049 
2050  //
2051  // Do not replace the divisions by max with multiplications by 1/max.
2052  // Computing 1/max can overflow but the divisions below will always
2053  // produce results less than or equal to 1.
2054  //
2055 
2056  absX /= max;
2057  absY /= max;
2058  absZ /= max;
2059  absW /= max;
2060 
2061  return max *
2062  Math<T>::sqrt (absX * absX + absY * absY + absZ * absZ + absW * absW);
2063 }
2064 
2065 template <class T>
2066 inline T
2068 {
2069  T length2 = dot (*this);
2070 
2071  if (length2 < T (2) * limits<T>::smallest())
2072  return lengthTiny();
2073 
2074  return Math<T>::sqrt (length2);
2075 }
2076 
2077 template <class T>
2078 inline T
2080 {
2081  return dot (*this);
2082 }
2083 
2084 template <class T>
2085 const Vec4<T> &
2087 {
2088  T l = length();
2089 
2090  if (l != T (0))
2091  {
2092  //
2093  // Do not replace the divisions by l with multiplications by 1/l.
2094  // Computing 1/l can overflow but the divisions below will always
2095  // produce results less than or equal to 1.
2096  //
2097 
2098  x /= l;
2099  y /= l;
2100  z /= l;
2101  w /= l;
2102  }
2103 
2104  return *this;
2105 }
2106 
2107 template <class T>
2108 const Vec4<T> &
2110 {
2111  T l = length();
2112 
2113  if (l == T (0))
2114  throw NullVecExc ("Cannot normalize null vector.");
2115 
2116  x /= l;
2117  y /= l;
2118  z /= l;
2119  w /= l;
2120  return *this;
2121 }
2122 
2123 template <class T>
2124 inline
2125 const Vec4<T> &
2127 {
2128  T l = length();
2129  x /= l;
2130  y /= l;
2131  z /= l;
2132  w /= l;
2133  return *this;
2134 }
2135 
2136 template <class T>
2137 Vec4<T>
2139 {
2140  T l = length();
2141 
2142  if (l == T (0))
2143  return Vec4 (T (0));
2144 
2145  return Vec4 (x / l, y / l, z / l, w / l);
2146 }
2147 
2148 template <class T>
2149 Vec4<T>
2150 Vec4<T>::normalizedExc () const throw (IEX_NAMESPACE::MathExc)
2151 {
2152  T l = length();
2153 
2154  if (l == T (0))
2155  throw NullVecExc ("Cannot normalize null vector.");
2156 
2157  return Vec4 (x / l, y / l, z / l, w / l);
2158 }
2159 
2160 template <class T>
2161 inline
2162 Vec4<T>
2164 {
2165  T l = length();
2166  return Vec4 (x / l, y / l, z / l, w / l);
2167 }
2168 
2169 //-----------------------------
2170 // Stream output implementation
2171 //-----------------------------
2172 
2173 template <class T>
2174 std::ostream &
2175 operator << (std::ostream &s, const Vec2<T> &v)
2176 {
2177  return s << '(' << v.x << ' ' << v.y << ')';
2178 }
2179 
2180 template <class T>
2181 std::ostream &
2182 operator << (std::ostream &s, const Vec3<T> &v)
2183 {
2184  return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')';
2185 }
2186 
2187 template <class T>
2188 std::ostream &
2189 operator << (std::ostream &s, const Vec4<T> &v)
2190 {
2191  return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ' ' << v.w << ')';
2192 }
2193 
2194 
2195 //-----------------------------------------
2196 // Implementation of reverse multiplication
2197 //-----------------------------------------
2198 
2199 template <class T>
2200 inline Vec2<T>
2202 {
2203  return Vec2<T> (a * v.x, a * v.y);
2204 }
2205 
2206 template <class T>
2207 inline Vec3<T>
2209 {
2210  return Vec3<T> (a * v.x, a * v.y, a * v.z);
2211 }
2212 
2213 template <class T>
2214 inline Vec4<T>
2216 {
2217  return Vec4<T> (a * v.x, a * v.y, a * v.z, a * v.w);
2218 }
2219 
2220 
2221 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
2222 #pragma warning(pop)
2223 #endif
2224 
2226 
2227 #endif // INCLUDED_IMATHVEC_H
const Vec3 & negate()
Definition: ImathVec.h:1553
#define IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
T BaseType
Definition: ImathVec.h:653
static T baseTypeMin()
Definition: ImathVec.h:247
Mat3< typename promote< S, T >::type > operator*(S scalar, const Mat3< T > &m)
Returns M, where for .
Definition: Mat3.h:615
Vec2 operator*(const Vec2 &v) const
Definition: ImathVec.h:1099
const Vec3 & normalizeNonNull()
Definition: ImathVec.h:1720
Vec3 operator*(const Vec3 &v) const
Definition: ImathVec.h:1583
T z
Definition: ImathVec.h:275
T length2() const
Definition: ImathVec.h:1675
Vec4< T > normalizedExc() const
Definition: ImathVec.h:2150
T dot(const Vec2 &v) const
Definition: ImathVec.h:1004
bool operator==(const Vec2< S > &v) const
Definition: ImathVec.h:967
bool operator!=(const Vec3< S > &v) const
Definition: ImathVec.h:1438
const Vec2 & normalize()
Definition: ImathVec.h:1191
static T baseTypeMax()
Definition: ImathVec.h:248
T length() const
Definition: ImathVec.h:1172
Vec4< float > V4f
Definition: ImathVec.h:697
#define IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
Vec3 operator-() const
Definition: ImathVec.h:1546
const Vec4 & operator/=(const Vec4 &v)
Definition: ImathVec.h:1993
Vec3 cross(const Vec3 &v) const
Definition: ImathVec.h:1481
const GLdouble * v
Definition: glcorearb.h:836
static T baseTypeMin()
Definition: ImathVec.h:641
Vec3< int > V3i
Definition: ImathVec.h:692
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:847
Vec4 operator/(const Vec4 &v) const
Definition: ImathVec.h:2015
const Vec2 & operator=(const Vec2 &v)
Definition: ImathVec.h:907
Vec2< int > V2i
Definition: ImathVec.h:688
const Vec4 & normalizeNonNull()
Definition: ImathVec.h:2126
T length2() const
Definition: ImathVec.h:2079
bool operator!=(const Vec4< S > &v) const
Definition: ImathVec.h:1859
bool equalWithRelError(T x1, T x2, T e)
Definition: ImathMath.h:200
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
Vec2< short > V2s
Definition: ImathVec.h:687
bool equalWithRelError(const Vec3< T > &v, T e) const
Definition: ImathVec.h:1456
const Vec4 & normalize()
Definition: ImathVec.h:2086
const Vec2 & operator+=(const Vec2 &v)
Definition: ImathVec.h:1033
GLint y
Definition: glcorearb.h:102
T operator^(const Vec2 &v) const
Definition: ImathVec.h:1011
static T min()
bool equalWithRelError(const Vec4< T > &v, T e) const
Definition: ImathVec.h:1877
Vec4()
Definition: ImathVec.h:1783
Vec4 operator+(const Vec4 &v) const
Definition: ImathVec.h:1914
Vec4< int > V4i
Definition: ImathVec.h:696
static T max()
Vec3 operator+(const Vec3 &v) const
Definition: ImathVec.h:1522
Vec3< short > V3s
Definition: ImathVec.h:691
static unsigned int dimensions()
Definition: ImathVec.h:240
T & operator[](int i)
Definition: ImathVec.h:1769
png_uint_32 i
Definition: png.h:2877
const Vec3 & operator/=(const Vec3 &v)
Definition: ImathVec.h:1597
bool equalWithRelError(const Vec2< T > &v, T e) const
Definition: ImathVec.h:993
Vec3< T > normalizedExc() const
Definition: ImathVec.h:1743
const hboost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:132
T operator%(const Vec2 &v) const
Definition: ImathVec.h:1026
Vec2 operator/(const Vec2 &v) const
Definition: ImathVec.h:1131
static T baseTypeEpsilon()
Definition: ImathVec.h:644
Vec3< double > V3d
Definition: ImathVec.h:694
T BaseType
Definition: ImathVec.h:471
T z
Definition: ImathVec.h:488
bool equalWithAbsError(const Vec4< T > &v, T e) const
Definition: ImathVec.h:1866
T x
Definition: ImathVec.h:77
static T baseTypeMax()
Definition: ImathVec.h:642
static T epsilon()
T x
Definition: ImathVec.h:275
const Vec4 & operator+=(const Vec4 &v)
Definition: ImathVec.h:1903
const Vec3 & operator%=(const Vec3 &v)
Definition: ImathVec.h:1490
Vec2< T > normalizedNonNull() const
Definition: ImathVec.h:1262
void setValue(S a, S b, S c)
Definition: ImathVec.h:1376
Vec3< T > normalizedNonNull() const
Definition: ImathVec.h:1756
Vec2()
Definition: ImathVec.h:868
const Vec4 & normalizeExc()
Definition: ImathVec.h:2109
T y
Definition: ImathVec.h:77
T dot(const Vec3 &v) const
Definition: ImathVec.h:1467
T operator^(const Vec3 &v) const
Definition: ImathVec.h:1474
fpreal64 dot(const CE_VectorT< T > &a, const CE_VectorT< T > &b)
Definition: CE_Vector.h:218
bool equalWithAbsError(const Vec2< T > &v, T e) const
Definition: ImathVec.h:982
Vec4< T > normalizedNonNull() const
Definition: ImathVec.h:2163
const Vec3 & normalizeExc()
Definition: ImathVec.h:1704
Vec3< T > normalized() const
Definition: ImathVec.h:1731
const Vec3 & operator=(const Vec3 &v)
Definition: ImathVec.h:1331
Vec2< double > V2d
Definition: ImathVec.h:690
const Vec4 & negate()
Definition: ImathVec.h:1946
const Vec3 & operator*=(const Vec3 &v)
Definition: ImathVec.h:1563
Vec4 operator*(const Vec4 &v) const
Definition: ImathVec.h:1979
T length() const
Definition: ImathVec.h:1663
T dot(const Vec4 &v) const
Definition: ImathVec.h:1888
const Vec3 & normalize()
Definition: ImathVec.h:1682
Vec2 operator-() const
Definition: ImathVec.h:1065
static T baseTypeSmallest()
Definition: ImathVec.h:461
GLint GLenum GLboolean normalized
Definition: glcorearb.h:871
GridType::Ptr normalize(const GridType &grid, bool threaded, InterruptT *interrupt)
Normalize the vectors of the given vector-valued grid.
Vec3 operator%(const Vec3 &v) const
Definition: ImathVec.h:1503
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
T * getValue()
Definition: ImathVec.h:1415
bool equalWithAbsError(const Vec3< T > &v, T e) const
Definition: ImathVec.h:1445
Vec2< float > V2f
Definition: ImathVec.h:689
#define IEX_NAMESPACE
Definition: IlmBaseConfig.h:10
bool operator==(const Vec4< S > &v) const
Definition: ImathVec.h:1851
Vec3< float > V3f
Definition: ImathVec.h:693
static T baseTypeEpsilon()
Definition: ImathVec.h:250
T cross(const Vec2 &v) const
Definition: ImathVec.h:1018
const Vec4 & operator*=(const Vec4 &v)
Definition: ImathVec.h:1957
const Vec2 & operator-=(const Vec2 &v)
Definition: ImathVec.h:1049
static T baseTypeEpsilon()
Definition: ImathVec.h:462
T x
Definition: ImathVec.h:488
T & operator[](int i)
Definition: ImathVec.h:854
Vec2< T > normalized() const
Definition: ImathVec.h:1237
T & operator[](int i)
Definition: ImathVec.h:1275
const Vec4 & operator=(const Vec4 &v)
Definition: ImathVec.h:1828
static unsigned int dimensions()
Definition: ImathVec.h:634
bool operator==(const Vec3< S > &v) const
Definition: ImathVec.h:1430
T length() const
Definition: ImathVec.h:2067
T * getValue()
Definition: ImathVec.h:952
GLint GLenum GLint x
Definition: glcorearb.h:408
const Vec2 & operator/=(const Vec2 &v)
Definition: ImathVec.h:1113
const Vec3 & operator+=(const Vec3 &v)
Definition: ImathVec.h:1512
static T smallest()
InfException
Definition: ImathVec.h:66
T length2() const
Definition: ImathVec.h:1184
static T baseTypeSmallest()
Definition: ImathVec.h:643
T y
Definition: ImathVec.h:275
Vec4< T > normalized() const
Definition: ImathVec.h:2138
Vec3 operator/(const Vec3 &v) const
Definition: ImathVec.h:1617
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
Vec4 operator-() const
Definition: ImathVec.h:1939
const Vec2 & normalizeNonNull()
Definition: ImathVec.h:1227
void setValue(S a, S b)
Definition: ImathVec.h:917
Vec2 operator+(const Vec2 &v) const
Definition: ImathVec.h:1042
#define const
Definition: zconf.h:214
const Vec2 & normalizeExc()
Definition: ImathVec.h:1212
const Vec3 & operator-=(const Vec3 &v)
Definition: ImathVec.h:1529
bool operator!=(const Vec2< S > &v) const
Definition: ImathVec.h:975
const Vec2 & operator*=(const Vec2 &v)
Definition: ImathVec.h:1081
static T baseTypeMax()
Definition: ImathVec.h:460
Vec4< short > V4s
Definition: ImathVec.h:695
static T sqrt(T x)
Definition: ImathMath.h:115
Vec3()
Definition: ImathVec.h:1289
T BaseType
Definition: ImathVec.h:259
static T baseTypeSmallest()
Definition: ImathVec.h:249
T w
Definition: ImathVec.h:488
static unsigned int dimensions()
Definition: ImathVec.h:452
static T baseTypeMin()
Definition: ImathVec.h:459
T y
Definition: ImathVec.h:488
Vec2< T > normalizedExc() const
Definition: ImathVec.h:1249
T operator^(const Vec4 &v) const
Definition: ImathVec.h:1895
bool equalWithAbsError(T x1, T x2, T e)
Definition: ImathMath.h:192
const Vec2 & negate()
Definition: ImathVec.h:1072
Vec4< double > V4d
Definition: ImathVec.h:698
const Vec4 & operator-=(const Vec4 &v)
Definition: ImathVec.h:1921
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:794