Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / include / OpenEXR / ImathVec.h
1 ///////////////////////////////////////////////////////////////////////////
2 //
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 //
33 ///////////////////////////////////////////////////////////////////////////
34
35
36
37 #ifndef INCLUDED_IMATHVEC_H
38 #define INCLUDED_IMATHVEC_H
39
40 //----------------------------------------------------
41 //
42 //      2D and 3D 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(disable:4290)
55 #endif
56
57
58 namespace Imath {
59
60
61 template <class T> class Vec2
62 {
63   public:
64
65     //-------------------
66     // Access to elements
67     //-------------------
68
69     T                   x, y;
70
71     T &                 operator [] (int i);
72     const T &           operator [] (int i) const;
73
74
75     //-------------
76     // Constructors
77     //-------------
78
79     Vec2 ();                        // no initialization
80     explicit Vec2 (T a);            // (a a)
81     Vec2 (T a, T b);                // (a b)
82
83
84     //---------------------------------
85     // Copy constructors and assignment
86     //---------------------------------
87
88     Vec2 (const Vec2 &v);
89     template <class S> Vec2 (const Vec2<S> &v);
90
91     const Vec2 &        operator = (const Vec2 &v);
92
93
94     //----------------------
95     // Compatibility with Sb
96     //----------------------
97
98     template <class S>
99     void                setValue (S a, S b);
100
101     template <class S>
102     void                setValue (const Vec2<S> &v);
103
104     template <class S>
105     void                getValue (S &a, S &b) const;
106
107     template <class S>
108     void                getValue (Vec2<S> &v) const;
109
110     T *                 getValue ();
111     const T *           getValue () const;
112
113     
114     //---------
115     // Equality
116     //---------
117
118     template <class S>
119     bool                operator == (const Vec2<S> &v) const;
120
121     template <class S>
122     bool                operator != (const Vec2<S> &v) const;
123
124
125     //-----------------------------------------------------------------------
126     // Compare two vectors and test if they are "approximately equal":
127     //
128     // equalWithAbsError (v, e)
129     //
130     //      Returns true if the coefficients of this and v are the same with
131     //      an absolute error of no more than e, i.e., for all i
132     //
133     //      abs (this[i] - v[i]) <= e
134     //
135     // equalWithRelError (v, e)
136     //
137     //      Returns true if the coefficients of this and v are the same with
138     //      a relative error of no more than e, i.e., for all i
139     //
140     //      abs (this[i] - v[i]) <= e * abs (this[i])
141     //-----------------------------------------------------------------------
142
143     bool                equalWithAbsError (const Vec2<T> &v, T e) const;
144     bool                equalWithRelError (const Vec2<T> &v, T e) const;
145
146     //------------
147     // Dot product
148     //------------
149
150     T                   dot (const Vec2 &v) const;
151     T                   operator ^ (const Vec2 &v) const;
152
153
154     //------------------------------------------------
155     // Right-handed cross product, i.e. z component of
156     // Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0)
157     //------------------------------------------------
158
159     T                   cross (const Vec2 &v) const;
160     T                   operator % (const Vec2 &v) const;
161
162
163     //------------------------
164     // Component-wise addition
165     //------------------------
166
167     const Vec2 &        operator += (const Vec2 &v);
168     Vec2                operator + (const Vec2 &v) const;
169
170
171     //---------------------------
172     // Component-wise subtraction
173     //---------------------------
174
175     const Vec2 &        operator -= (const Vec2 &v);
176     Vec2                operator - (const Vec2 &v) const;
177
178
179     //------------------------------------
180     // Component-wise multiplication by -1
181     //------------------------------------
182
183     Vec2                operator - () const;
184     const Vec2 &        negate ();
185
186
187     //------------------------------
188     // Component-wise multiplication
189     //------------------------------
190
191     const Vec2 &        operator *= (const Vec2 &v);
192     const Vec2 &        operator *= (T a);
193     Vec2                operator * (const Vec2 &v) const;
194     Vec2                operator * (T a) const;
195
196
197     //------------------------
198     // Component-wise division
199     //------------------------
200
201     const Vec2 &        operator /= (const Vec2 &v);
202     const Vec2 &        operator /= (T a);
203     Vec2                operator / (const Vec2 &v) const;
204     Vec2                operator / (T a) const;
205
206
207     //----------------------------------------------------------------
208     // Length and normalization:  If v.length() is 0.0, v.normalize()
209     // and v.normalized() produce a null vector; v.normalizeExc() and
210     // v.normalizedExc() throw a NullVecExc.
211     // v.normalizeNonNull() and v.normalizedNonNull() are slightly
212     // faster than the other normalization routines, but if v.length()
213     // is 0.0, the result is undefined.
214     //----------------------------------------------------------------
215
216     T                   length () const;
217     T                   length2 () const;
218
219     const Vec2 &        normalize ();           // modifies *this
220     const Vec2 &        normalizeExc () throw (Iex::MathExc);
221     const Vec2 &        normalizeNonNull ();
222
223     Vec2<T>             normalized () const;    // does not modify *this
224     Vec2<T>             normalizedExc () const throw (Iex::MathExc);
225     Vec2<T>             normalizedNonNull () const;
226
227
228     //--------------------------------------------------------
229     // Number of dimensions, i.e. number of elements in a Vec2
230     //--------------------------------------------------------
231
232     static unsigned int dimensions() {return 2;}
233
234
235     //-------------------------------------------------
236     // Limitations of type T (see also class limits<T>)
237     //-------------------------------------------------
238
239     static T            baseTypeMin()           {return limits<T>::min();}
240     static T            baseTypeMax()           {return limits<T>::max();}
241     static T            baseTypeSmallest()      {return limits<T>::smallest();}
242     static T            baseTypeEpsilon()       {return limits<T>::epsilon();}
243
244
245     //--------------------------------------------------------------
246     // Base type -- in templates, which accept a parameter, V, which
247     // could be either a Vec2<T> or a Vec3<T>, you can refer to T as
248     // V::BaseType
249     //--------------------------------------------------------------
250
251     typedef T           BaseType;
252 };
253
254
255 template <class T> class Vec3
256 {
257   public:
258
259     //-------------------
260     // Access to elements
261     //-------------------
262
263     T                   x, y, z;
264
265     T &                 operator [] (int i);
266     const T &           operator [] (int i) const;
267
268
269     //-------------
270     // Constructors
271     //-------------
272
273     Vec3 ();                       // no initialization
274     explicit Vec3 (T a);           // (a a a)
275     Vec3 (T a, T b, T c);          // (a b c)
276
277
278     //---------------------------------
279     // Copy constructors and assignment
280     //---------------------------------
281
282     Vec3 (const Vec3 &v);
283     template <class S> Vec3 (const Vec3<S> &v);
284
285     const Vec3 &        operator = (const Vec3 &v);
286
287
288     //----------------------
289     // Compatibility with Sb
290     //----------------------
291
292     template <class S>
293     void                setValue (S a, S b, S c);
294
295     template <class S>
296     void                setValue (const Vec3<S> &v);
297
298     template <class S>
299     void                getValue (S &a, S &b, S &c) const;
300
301     template <class S>
302     void                getValue (Vec3<S> &v) const;
303
304     T *                 getValue();
305     const T *           getValue() const;
306
307
308     //---------
309     // Equality
310     //---------
311
312     template <class S>
313     bool                operator == (const Vec3<S> &v) const;
314
315     template <class S>
316     bool                operator != (const Vec3<S> &v) const;
317
318     //-----------------------------------------------------------------------
319     // Compare two vectors and test if they are "approximately equal":
320     //
321     // equalWithAbsError (v, e)
322     //
323     //      Returns true if the coefficients of this and v are the same with
324     //      an absolute error of no more than e, i.e., for all i
325     //
326     //      abs (this[i] - v[i]) <= e
327     //
328     // equalWithRelError (v, e)
329     //
330     //      Returns true if the coefficients of this and v are the same with
331     //      a relative error of no more than e, i.e., for all i
332     //
333     //      abs (this[i] - v[i]) <= e * abs (this[i])
334     //-----------------------------------------------------------------------
335
336     bool                equalWithAbsError (const Vec3<T> &v, T e) const;
337     bool                equalWithRelError (const Vec3<T> &v, T e) const;
338
339     //------------
340     // Dot product
341     //------------
342
343     T                   dot (const Vec3 &v) const;
344     T                   operator ^ (const Vec3 &v) const;
345
346
347     //---------------------------
348     // Right-handed cross product
349     //---------------------------
350
351     Vec3                cross (const Vec3 &v) const;
352     const Vec3 &        operator %= (const Vec3 &v);
353     Vec3                operator % (const Vec3 &v) const;
354
355
356     //------------------------
357     // Component-wise addition
358     //------------------------
359
360     const Vec3 &        operator += (const Vec3 &v);
361     Vec3                operator + (const Vec3 &v) const;
362
363
364     //---------------------------
365     // Component-wise subtraction
366     //---------------------------
367
368     const Vec3 &        operator -= (const Vec3 &v);
369     Vec3                operator - (const Vec3 &v) const;
370
371
372     //------------------------------------
373     // Component-wise multiplication by -1
374     //------------------------------------
375
376     Vec3                operator - () const;
377     const Vec3 &        negate ();
378
379
380     //------------------------------
381     // Component-wise multiplication
382     //------------------------------
383
384     const Vec3 &        operator *= (const Vec3 &v);
385     const Vec3 &        operator *= (T a);
386     Vec3                operator * (const Vec3 &v) const;
387     Vec3                operator * (T a) const;
388
389
390     //------------------------
391     // Component-wise division
392     //------------------------
393
394     const Vec3 &        operator /= (const Vec3 &v);
395     const Vec3 &        operator /= (T a);
396     Vec3                operator / (const Vec3 &v) const;
397     Vec3                operator / (T a) const;
398
399
400     //----------------------------------------------------------------
401     // Length and normalization:  If v.length() is 0.0, v.normalize()
402     // and v.normalized() produce a null vector; v.normalizeExc() and
403     // v.normalizedExc() throw a NullVecExc.
404     // v.normalizeNonNull() and v.normalizedNonNull() are slightly
405     // faster than the other normalization routines, but if v.length()
406     // is 0.0, the result is undefined.
407     //----------------------------------------------------------------
408
409     T                   length () const;
410     T                   length2 () const;
411
412     const Vec3 &        normalize ();           // modifies *this
413     const Vec3 &        normalizeExc () throw (Iex::MathExc);
414     const Vec3 &        normalizeNonNull ();
415
416     Vec3<T>             normalized () const;    // does not modify *this
417     Vec3<T>             normalizedExc () const throw (Iex::MathExc);
418     Vec3<T>             normalizedNonNull () const;
419
420
421     //--------------------------------------------------------
422     // Number of dimensions, i.e. number of elements in a Vec3
423     //--------------------------------------------------------
424
425     static unsigned int dimensions() {return 3;}
426
427
428     //-------------------------------------------------
429     // Limitations of type T (see also class limits<T>)
430     //-------------------------------------------------
431
432     static T            baseTypeMin()           {return limits<T>::min();}
433     static T            baseTypeMax()           {return limits<T>::max();}
434     static T            baseTypeSmallest()      {return limits<T>::smallest();}
435     static T            baseTypeEpsilon()       {return limits<T>::epsilon();}
436
437
438     //--------------------------------------------------------------
439     // Base type -- in templates, which accept a parameter, V, which
440     // could be either a Vec2<T> or a Vec3<T>, you can refer to T as
441     // V::BaseType
442     //--------------------------------------------------------------
443
444     typedef T           BaseType;
445 };
446
447
448 //--------------
449 // Stream output
450 //--------------
451
452 template <class T>
453 std::ostream &  operator << (std::ostream &s, const Vec2<T> &v);
454
455 template <class T>
456 std::ostream &  operator << (std::ostream &s, const Vec3<T> &v);
457
458
459 //----------------------------------------------------
460 // Reverse multiplication: S * Vec2<T> and S * Vec3<T>
461 //----------------------------------------------------
462
463 template <class T> Vec2<T>      operator * (T a, const Vec2<T> &v);
464 template <class T> Vec3<T>      operator * (T a, const Vec3<T> &v);
465
466
467 //-------------------------
468 // Typedefs for convenience
469 //-------------------------
470
471 typedef Vec2 <short>  V2s;
472 typedef Vec2 <int>    V2i;
473 typedef Vec2 <float>  V2f;
474 typedef Vec2 <double> V2d;
475 typedef Vec3 <short>  V3s;
476 typedef Vec3 <int>    V3i;
477 typedef Vec3 <float>  V3f;
478 typedef Vec3 <double> V3d;
479
480
481 //-------------------------------------------------------------------
482 // Specializations for Vec2<short>, Vec2<int>, Vec3<short>, Vec3<int>
483 //-------------------------------------------------------------------
484
485 // Vec2<short>
486
487 template <> short
488 Vec2<short>::length () const;
489
490 template <> const Vec2<short> &
491 Vec2<short>::normalize ();
492
493 template <> const Vec2<short> &
494 Vec2<short>::normalizeExc () throw (Iex::MathExc);
495
496 template <> const Vec2<short> &
497 Vec2<short>::normalizeNonNull ();
498
499 template <> Vec2<short>
500 Vec2<short>::normalized () const;
501
502 template <> Vec2<short>
503 Vec2<short>::normalizedExc () const throw (Iex::MathExc);
504
505 template <> Vec2<short>
506 Vec2<short>::normalizedNonNull () const;
507
508
509 // Vec2<int>
510
511 template <> int
512 Vec2<int>::length () const;
513
514 template <> const Vec2<int> &
515 Vec2<int>::normalize ();
516
517 template <> const Vec2<int> &
518 Vec2<int>::normalizeExc () throw (Iex::MathExc);
519
520 template <> const Vec2<int> &
521 Vec2<int>::normalizeNonNull ();
522
523 template <> Vec2<int>
524 Vec2<int>::normalized () const;
525
526 template <> Vec2<int>
527 Vec2<int>::normalizedExc () const throw (Iex::MathExc);
528
529 template <> Vec2<int>
530 Vec2<int>::normalizedNonNull () const;
531
532
533 // Vec3<short>
534
535 template <> short
536 Vec3<short>::length () const;
537
538 template <> const Vec3<short> &
539 Vec3<short>::normalize ();
540
541 template <> const Vec3<short> &
542 Vec3<short>::normalizeExc () throw (Iex::MathExc);
543
544 template <> const Vec3<short> &
545 Vec3<short>::normalizeNonNull ();
546
547 template <> Vec3<short>
548 Vec3<short>::normalized () const;
549
550 template <> Vec3<short>
551 Vec3<short>::normalizedExc () const throw (Iex::MathExc);
552
553 template <> Vec3<short>
554 Vec3<short>::normalizedNonNull () const;
555
556
557 // Vec3<int>
558
559 template <> int
560 Vec3<int>::length () const;
561
562 template <> const Vec3<int> &
563 Vec3<int>::normalize ();
564
565 template <> const Vec3<int> &
566 Vec3<int>::normalizeExc () throw (Iex::MathExc);
567
568 template <> const Vec3<int> &
569 Vec3<int>::normalizeNonNull ();
570
571 template <> Vec3<int>
572 Vec3<int>::normalized () const;
573
574 template <> Vec3<int>
575 Vec3<int>::normalizedExc () const throw (Iex::MathExc);
576
577 template <> Vec3<int>
578 Vec3<int>::normalizedNonNull () const;
579
580
581 //------------------------
582 // Implementation of Vec2:
583 //------------------------
584
585 template <class T>
586 inline T &
587 Vec2<T>::operator [] (int i)
588 {
589     return (&x)[i];
590 }
591
592 template <class T>
593 inline const T &
594 Vec2<T>::operator [] (int i) const
595 {
596     return (&x)[i];
597 }
598
599 template <class T>
600 inline
601 Vec2<T>::Vec2 ()
602 {
603     // empty
604 }
605
606 template <class T>
607 inline
608 Vec2<T>::Vec2 (T a)
609 {
610     x = y = a;
611 }
612
613 template <class T>
614 inline
615 Vec2<T>::Vec2 (T a, T b)
616 {
617     x = a;
618     y = b;
619 }
620
621 template <class T>
622 inline
623 Vec2<T>::Vec2 (const Vec2 &v)
624 {
625     x = v.x;
626     y = v.y;
627 }
628
629 template <class T>
630 template <class S>
631 inline
632 Vec2<T>::Vec2 (const Vec2<S> &v)
633 {
634     x = T (v.x);
635     y = T (v.y);
636 }
637
638 template <class T>
639 inline const Vec2<T> &
640 Vec2<T>::operator = (const Vec2 &v)
641 {
642     x = v.x;
643     y = v.y;
644     return *this;
645 }
646
647 template <class T>
648 template <class S>
649 inline void
650 Vec2<T>::setValue (S a, S b)
651 {
652     x = T (a);
653     y = T (b);
654 }
655
656 template <class T>
657 template <class S>
658 inline void
659 Vec2<T>::setValue (const Vec2<S> &v)
660 {
661     x = T (v.x);
662     y = T (v.y);
663 }
664
665 template <class T>
666 template <class S>
667 inline void
668 Vec2<T>::getValue (S &a, S &b) const
669 {
670     a = S (x);
671     b = S (y);
672 }
673
674 template <class T>
675 template <class S>
676 inline void
677 Vec2<T>::getValue (Vec2<S> &v) const
678 {
679     v.x = S (x);
680     v.y = S (y);
681 }
682
683 template <class T>
684 inline T *
685 Vec2<T>::getValue()
686 {
687     return (T *) &x;
688 }
689
690 template <class T>
691 inline const T *
692 Vec2<T>::getValue() const
693 {
694     return (const T *) &x;
695 }
696
697 template <class T>
698 template <class S>
699 inline bool
700 Vec2<T>::operator == (const Vec2<S> &v) const
701 {
702     return x == v.x && y == v.y;
703 }
704
705 template <class T>
706 template <class S>
707 inline bool
708 Vec2<T>::operator != (const Vec2<S> &v) const
709 {
710     return x != v.x || y != v.y;
711 }
712
713 template <class T>
714 bool
715 Vec2<T>::equalWithAbsError (const Vec2<T> &v, T e) const
716 {
717     for (int i = 0; i < 2; i++)
718         if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
719             return false;
720
721     return true;
722 }
723
724 template <class T>
725 bool
726 Vec2<T>::equalWithRelError (const Vec2<T> &v, T e) const
727 {
728     for (int i = 0; i < 2; i++)
729         if (!Imath::equalWithRelError ((*this)[i], v[i], e))
730             return false;
731
732     return true;
733 }
734
735 template <class T>
736 inline T
737 Vec2<T>::dot (const Vec2 &v) const
738 {
739     return x * v.x + y * v.y;
740 }
741
742 template <class T>
743 inline T
744 Vec2<T>::operator ^ (const Vec2 &v) const
745 {
746     return dot (v);
747 }
748
749 template <class T>
750 inline T
751 Vec2<T>::cross (const Vec2 &v) const
752 {
753     return x * v.y - y * v.x;
754
755 }
756
757 template <class T>
758 inline T
759 Vec2<T>::operator % (const Vec2 &v) const
760 {
761     return x * v.y - y * v.x;
762 }
763
764 template <class T>
765 inline const Vec2<T> &
766 Vec2<T>::operator += (const Vec2 &v)
767 {
768     x += v.x;
769     y += v.y;
770     return *this;
771 }
772
773 template <class T>
774 inline Vec2<T>
775 Vec2<T>::operator + (const Vec2 &v) const
776 {
777     return Vec2 (x + v.x, y + v.y);
778 }
779
780 template <class T>
781 inline const Vec2<T> &
782 Vec2<T>::operator -= (const Vec2 &v)
783 {
784     x -= v.x;
785     y -= v.y;
786     return *this;
787 }
788
789 template <class T>
790 inline Vec2<T>
791 Vec2<T>::operator - (const Vec2 &v) const
792 {
793     return Vec2 (x - v.x, y - v.y);
794 }
795
796 template <class T>
797 inline Vec2<T>
798 Vec2<T>::operator - () const
799 {
800     return Vec2 (-x, -y);
801 }
802
803 template <class T>
804 inline const Vec2<T> &
805 Vec2<T>::negate ()
806 {
807     x = -x;
808     y = -y;
809     return *this;
810 }
811
812 template <class T>
813 inline const Vec2<T> &
814 Vec2<T>::operator *= (const Vec2 &v)
815 {
816     x *= v.x;
817     y *= v.y;
818     return *this;
819 }
820
821 template <class T>
822 inline const Vec2<T> &
823 Vec2<T>::operator *= (T a)
824 {
825     x *= a;
826     y *= a;
827     return *this;
828 }
829
830 template <class T>
831 inline Vec2<T>
832 Vec2<T>::operator * (const Vec2 &v) const
833 {
834     return Vec2 (x * v.x, y * v.y);
835 }
836
837 template <class T>
838 inline Vec2<T>
839 Vec2<T>::operator * (T a) const
840 {
841     return Vec2 (x * a, y * a);
842 }
843
844 template <class T>
845 inline const Vec2<T> &
846 Vec2<T>::operator /= (const Vec2 &v)
847 {
848     x /= v.x;
849     y /= v.y;
850     return *this;
851 }
852
853 template <class T>
854 inline const Vec2<T> &
855 Vec2<T>::operator /= (T a)
856 {
857     x /= a;
858     y /= a;
859     return *this;
860 }
861
862 template <class T>
863 inline Vec2<T>
864 Vec2<T>::operator / (const Vec2 &v) const
865 {
866     return Vec2 (x / v.x, y / v.y);
867 }
868
869 template <class T>
870 inline Vec2<T>
871 Vec2<T>::operator / (T a) const
872 {
873     return Vec2 (x / a, y / a);
874 }
875
876 template <class T>
877 inline T
878 Vec2<T>::length () const
879 {
880     return Math<T>::sqrt (dot (*this));
881 }
882
883 template <class T>
884 inline T
885 Vec2<T>::length2 () const
886 {
887     return dot (*this);
888 }
889
890 template <class T>
891 const Vec2<T> &
892 Vec2<T>::normalize ()
893 {
894     T l = length();
895
896     if (l != 0)
897     {
898         x /= l;
899         y /= l;
900     }
901
902     return *this;
903 }
904
905 template <class T>
906 const Vec2<T> &
907 Vec2<T>::normalizeExc () throw (Iex::MathExc)
908 {
909     T l = length();
910
911     if (l == 0)
912         throw NullVecExc ("Cannot normalize null vector.");
913
914     x /= l;
915     y /= l;
916     return *this;
917 }
918
919 template <class T>
920 inline
921 const Vec2<T> &
922 Vec2<T>::normalizeNonNull ()
923 {
924     T l = length();
925     x /= l;
926     y /= l;
927     return *this;
928 }
929
930 template <class T>
931 Vec2<T>
932 Vec2<T>::normalized () const
933 {
934     T l = length();
935
936     if (l == 0)
937         return Vec2 (T (0));
938
939     return Vec2 (x / l, y / l);
940 }
941
942 template <class T>
943 Vec2<T>
944 Vec2<T>::normalizedExc () const throw (Iex::MathExc)
945 {
946     T l = length();
947
948     if (l == 0)
949         throw NullVecExc ("Cannot normalize null vector.");
950
951     return Vec2 (x / l, y / l);
952 }
953
954 template <class T>
955 inline
956 Vec2<T>
957 Vec2<T>::normalizedNonNull () const
958 {
959     T l = length();
960     return Vec2 (x / l, y / l);
961 }
962
963
964 //-----------------------
965 // Implementation of Vec3
966 //-----------------------
967
968 template <class T>
969 inline T &
970 Vec3<T>::operator [] (int i)
971 {
972     return (&x)[i];
973 }
974
975 template <class T>
976 inline const T &
977 Vec3<T>::operator [] (int i) const
978 {
979     return (&x)[i];
980 }
981
982 template <class T>
983 inline
984 Vec3<T>::Vec3 ()
985 {
986     // empty
987 }
988
989 template <class T>
990 inline
991 Vec3<T>::Vec3 (T a)
992 {
993     x = y = z = a;
994 }
995
996 template <class T>
997 inline
998 Vec3<T>::Vec3 (T a, T b, T c)
999 {
1000     x = a;
1001     y = b;
1002     z = c;
1003 }
1004
1005 template <class T>
1006 inline
1007 Vec3<T>::Vec3 (const Vec3 &v)
1008 {
1009     x = v.x;
1010     y = v.y;
1011     z = v.z;
1012 }
1013
1014 template <class T>
1015 template <class S>
1016 inline
1017 Vec3<T>::Vec3 (const Vec3<S> &v)
1018 {
1019     x = T (v.x);
1020     y = T (v.y);
1021     z = T (v.z);
1022 }
1023
1024 template <class T>
1025 inline const Vec3<T> &
1026 Vec3<T>::operator = (const Vec3 &v)
1027 {
1028     x = v.x;
1029     y = v.y;
1030     z = v.z;
1031     return *this;
1032 }
1033
1034 template <class T>
1035 template <class S>
1036 inline void
1037 Vec3<T>::setValue (S a, S b, S c)
1038 {
1039     x = T (a);
1040     y = T (b);
1041     z = T (c);
1042 }
1043
1044 template <class T>
1045 template <class S>
1046 inline void
1047 Vec3<T>::setValue (const Vec3<S> &v)
1048 {
1049     x = T (v.x);
1050     y = T (v.y);
1051     z = T (v.z);
1052 }
1053
1054 template <class T>
1055 template <class S>
1056 inline void
1057 Vec3<T>::getValue (S &a, S &b, S &c) const
1058 {
1059     a = S (x);
1060     b = S (y);
1061     c = S (z);
1062 }
1063
1064 template <class T>
1065 template <class S>
1066 inline void
1067 Vec3<T>::getValue (Vec3<S> &v) const
1068 {
1069     v.x = S (x);
1070     v.y = S (y);
1071     v.z = S (z);
1072 }
1073
1074 template <class T>
1075 inline T *
1076 Vec3<T>::getValue()
1077 {
1078     return (T *) &x;
1079 }
1080
1081 template <class T>
1082 inline const T *
1083 Vec3<T>::getValue() const
1084 {
1085     return (const T *) &x;
1086 }
1087
1088 template <class T>
1089 template <class S>
1090 inline bool
1091 Vec3<T>::operator == (const Vec3<S> &v) const
1092 {
1093     return x == v.x && y == v.y && z == v.z;
1094 }
1095
1096 template <class T>
1097 template <class S>
1098 inline bool
1099 Vec3<T>::operator != (const Vec3<S> &v) const
1100 {
1101     return x != v.x || y != v.y || z != v.z;
1102 }
1103
1104 template <class T>
1105 bool
1106 Vec3<T>::equalWithAbsError (const Vec3<T> &v, T e) const
1107 {
1108     for (int i = 0; i < 3; i++)
1109         if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
1110             return false;
1111
1112     return true;
1113 }
1114
1115 template <class T>
1116 bool
1117 Vec3<T>::equalWithRelError (const Vec3<T> &v, T e) const
1118 {
1119     for (int i = 0; i < 3; i++)
1120         if (!Imath::equalWithRelError ((*this)[i], v[i], e))
1121             return false;
1122
1123     return true;
1124 }
1125
1126 template <class T>
1127 inline T
1128 Vec3<T>::dot (const Vec3 &v) const
1129 {
1130     return x * v.x + y * v.y + z * v.z;
1131 }
1132
1133 template <class T>
1134 inline T
1135 Vec3<T>::operator ^ (const Vec3 &v) const
1136 {
1137     return dot (v);
1138 }
1139
1140 template <class T>
1141 inline Vec3<T>
1142 Vec3<T>::cross (const Vec3 &v) const
1143 {
1144     return Vec3 (y * v.z - z * v.y,
1145                  z * v.x - x * v.z,
1146                  x * v.y - y * v.x);
1147 }
1148
1149 template <class T>
1150 inline const Vec3<T> &
1151 Vec3<T>::operator %= (const Vec3 &v)
1152 {
1153     T a = y * v.z - z * v.y;
1154     T b = z * v.x - x * v.z;
1155     T c = x * v.y - y * v.x;
1156     x = a;
1157     y = b;
1158     z = c;
1159     return *this;
1160 }
1161
1162 template <class T>
1163 inline Vec3<T>
1164 Vec3<T>::operator % (const Vec3 &v) const
1165 {
1166     return Vec3 (y * v.z - z * v.y,
1167                  z * v.x - x * v.z,
1168                  x * v.y - y * v.x);
1169 }
1170
1171 template <class T>
1172 inline const Vec3<T> &
1173 Vec3<T>::operator += (const Vec3 &v)
1174 {
1175     x += v.x;
1176     y += v.y;
1177     z += v.z;
1178     return *this;
1179 }
1180
1181 template <class T>
1182 inline Vec3<T>
1183 Vec3<T>::operator + (const Vec3 &v) const
1184 {
1185     return Vec3 (x + v.x, y + v.y, z + v.z);
1186 }
1187
1188 template <class T>
1189 inline const Vec3<T> &
1190 Vec3<T>::operator -= (const Vec3 &v)
1191 {
1192     x -= v.x;
1193     y -= v.y;
1194     z -= v.z;
1195     return *this;
1196 }
1197
1198 template <class T>
1199 inline Vec3<T>
1200 Vec3<T>::operator - (const Vec3 &v) const
1201 {
1202     return Vec3 (x - v.x, y - v.y, z - v.z);
1203 }
1204
1205 template <class T>
1206 inline Vec3<T>
1207 Vec3<T>::operator - () const
1208 {
1209     return Vec3 (-x, -y, -z);
1210 }
1211
1212 template <class T>
1213 inline const Vec3<T> &
1214 Vec3<T>::negate ()
1215 {
1216     x = -x;
1217     y = -y;
1218     z = -z;
1219     return *this;
1220 }
1221
1222 template <class T>
1223 inline const Vec3<T> &
1224 Vec3<T>::operator *= (const Vec3 &v)
1225 {
1226     x *= v.x;
1227     y *= v.y;
1228     z *= v.z;
1229     return *this;
1230 }
1231
1232 template <class T>
1233 inline const Vec3<T> &
1234 Vec3<T>::operator *= (T a)
1235 {
1236     x *= a;
1237     y *= a;
1238     z *= a;
1239     return *this;
1240 }
1241
1242 template <class T>
1243 inline Vec3<T>
1244 Vec3<T>::operator * (const Vec3 &v) const
1245 {
1246     return Vec3 (x * v.x, y * v.y, z * v.z);
1247 }
1248
1249 template <class T>
1250 inline Vec3<T>
1251 Vec3<T>::operator * (T a) const
1252 {
1253     return Vec3 (x * a, y * a, z * a);
1254 }
1255
1256 template <class T>
1257 inline const Vec3<T> &
1258 Vec3<T>::operator /= (const Vec3 &v)
1259 {
1260     x /= v.x;
1261     y /= v.y;
1262     z /= v.z;
1263     return *this;
1264 }
1265
1266 template <class T>
1267 inline const Vec3<T> &
1268 Vec3<T>::operator /= (T a)
1269 {
1270     x /= a;
1271     y /= a;
1272     z /= a;
1273     return *this;
1274 }
1275
1276 template <class T>
1277 inline Vec3<T>
1278 Vec3<T>::operator / (const Vec3 &v) const
1279 {
1280     return Vec3 (x / v.x, y / v.y, z / v.z);
1281 }
1282
1283 template <class T>
1284 inline Vec3<T>
1285 Vec3<T>::operator / (T a) const
1286 {
1287     return Vec3 (x / a, y / a, z / a);
1288 }
1289
1290
1291 template <class T>
1292 inline T
1293 Vec3<T>::length () const
1294 {
1295     return Math<T>::sqrt (dot (*this));
1296 }
1297
1298 template <class T>
1299 inline T
1300 Vec3<T>::length2 () const
1301 {
1302     return dot (*this);
1303 }
1304
1305 template <class T>
1306 const Vec3<T> &
1307 Vec3<T>::normalize ()
1308 {
1309     T l = length();
1310
1311     if (l != 0)
1312     {
1313         x /= l;
1314         y /= l;
1315         z /= l;
1316     }
1317
1318     return *this;
1319 }
1320
1321 template <class T>
1322 const Vec3<T> &
1323 Vec3<T>::normalizeExc () throw (Iex::MathExc)
1324 {
1325     T l = length();
1326
1327     if (l == 0)
1328         throw NullVecExc ("Cannot normalize null vector.");
1329
1330     x /= l;
1331     y /= l;
1332     z /= l;
1333     return *this;
1334 }
1335
1336 template <class T>
1337 inline
1338 const Vec3<T> &
1339 Vec3<T>::normalizeNonNull ()
1340 {
1341     T l = length();
1342     x /= l;
1343     y /= l;
1344     z /= l;
1345     return *this;
1346 }
1347
1348 template <class T>
1349 Vec3<T>
1350 Vec3<T>::normalized () const
1351 {
1352     T l = length();
1353
1354     if (l == 0)
1355         return Vec3 (T (0));
1356
1357     return Vec3 (x / l, y / l, z / l);
1358 }
1359
1360 template <class T>
1361 Vec3<T>
1362 Vec3<T>::normalizedExc () const throw (Iex::MathExc)
1363 {
1364     T l = length();
1365
1366     if (l == 0)
1367         throw NullVecExc ("Cannot normalize null vector.");
1368
1369     return Vec3 (x / l, y / l, z / l);
1370 }
1371
1372 template <class T>
1373 inline
1374 Vec3<T>
1375 Vec3<T>::normalizedNonNull () const
1376 {
1377     T l = length();
1378     return Vec3 (x / l, y / l, z / l);
1379 }
1380
1381
1382 //-----------------------------
1383 // Stream output implementation
1384 //-----------------------------
1385
1386 template <class T>
1387 std::ostream &
1388 operator << (std::ostream &s, const Vec2<T> &v)
1389 {
1390     return s << '(' << v.x << ' ' << v.y << ')';
1391 }
1392
1393 template <class T>
1394 std::ostream &
1395 operator << (std::ostream &s, const Vec3<T> &v)
1396 {
1397     return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')';
1398 }
1399
1400
1401 //-----------------------------------------
1402 // Implementation of reverse multiplication
1403 //-----------------------------------------
1404
1405 template <class T>
1406 inline Vec2<T>
1407 operator * (T a, const Vec2<T> &v)
1408 {
1409     return Vec2<T> (a * v.x, a * v.y);
1410 }
1411
1412 template <class T>
1413 inline Vec3<T>
1414 operator * (T a, const Vec3<T> &v)
1415 {
1416     return Vec3<T> (a * v.x, a * v.y, a * v.z);
1417 }
1418
1419
1420 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
1421 #pragma warning(default:4290)
1422 #endif
1423
1424 } // namespace Imath
1425
1426 #endif