source: NonGTP/OpenEXR/include/Imath/ImathVec.h @ 855

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