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