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