Coverage Report

Created: 2023-12-08 06:53

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