1
///////////////////////////////////////////////////////////////////////////
3
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
6
// All rights reserved.
8
// Redistribution and use in source and binary forms, with or without
9
// modification, are permitted provided that the following conditions are
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
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.
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.
33
///////////////////////////////////////////////////////////////////////////
37
#ifndef INCLUDED_IMATHVEC_H
38
#define INCLUDED_IMATHVEC_H
40
//----------------------------------------------------
42
// 2D and 3D point/vector class templates!
44
//----------------------------------------------------
47
#include "ImathLimits.h"
48
#include "ImathMath.h"
52
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
53
// suppress exception specification warnings
54
#pragma warning(disable:4290)
61
template <class T> class Vec2
71
T & operator [] (int i);
72
const T & operator [] (int i) const;
79
Vec2 (); // no initialization
80
explicit Vec2 (T a); // (a a)
81
Vec2 (T a, T b); // (a b)
84
//---------------------------------
85
// Copy constructors and assignment
86
//---------------------------------
89
template <class S> Vec2 (const Vec2<S> &v);
91
const Vec2 & operator = (const Vec2 &v);
94
//----------------------
95
// Compatibility with Sb
96
//----------------------
99
void setValue (S a, S b);
102
void setValue (const Vec2<S> &v);
105
void getValue (S &a, S &b) const;
108
void getValue (Vec2<S> &v) const;
111
const T * getValue () const;
119
bool operator == (const Vec2<S> &v) const;
122
bool operator != (const Vec2<S> &v) const;
125
//-----------------------------------------------------------------------
126
// Compare two vectors and test if they are "approximately equal":
128
// equalWithAbsError (v, e)
130
// Returns true if the coefficients of this and v are the same with
131
// an absolute error of no more than e, i.e., for all i
133
// abs (this[i] - v[i]) <= e
135
// equalWithRelError (v, e)
137
// Returns true if the coefficients of this and v are the same with
138
// a relative error of no more than e, i.e., for all i
140
// abs (this[i] - v[i]) <= e * abs (this[i])
141
//-----------------------------------------------------------------------
143
bool equalWithAbsError (const Vec2<T> &v, T e) const;
144
bool equalWithRelError (const Vec2<T> &v, T e) const;
150
T dot (const Vec2 &v) const;
151
T operator ^ (const Vec2 &v) const;
154
//------------------------------------------------
155
// Right-handed cross product, i.e. z component of
156
// Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0)
157
//------------------------------------------------
159
T cross (const Vec2 &v) const;
160
T operator % (const Vec2 &v) const;
163
//------------------------
164
// Component-wise addition
165
//------------------------
167
const Vec2 & operator += (const Vec2 &v);
168
Vec2 operator + (const Vec2 &v) const;
171
//---------------------------
172
// Component-wise subtraction
173
//---------------------------
175
const Vec2 & operator -= (const Vec2 &v);
176
Vec2 operator - (const Vec2 &v) const;
179
//------------------------------------
180
// Component-wise multiplication by -1
181
//------------------------------------
183
Vec2 operator - () const;
184
const Vec2 & negate ();
187
//------------------------------
188
// Component-wise multiplication
189
//------------------------------
191
const Vec2 & operator *= (const Vec2 &v);
192
const Vec2 & operator *= (T a);
193
Vec2 operator * (const Vec2 &v) const;
194
Vec2 operator * (T a) const;
197
//------------------------
198
// Component-wise division
199
//------------------------
201
const Vec2 & operator /= (const Vec2 &v);
202
const Vec2 & operator /= (T a);
203
Vec2 operator / (const Vec2 &v) const;
204
Vec2 operator / (T a) const;
207
//----------------------------------------------------------------
208
// Length and normalization: If v.length() is 0.0, v.normalize()
209
// and v.normalized() produce a null vector; v.normalizeExc() and
210
// v.normalizedExc() throw a NullVecExc.
211
// v.normalizeNonNull() and v.normalizedNonNull() are slightly
212
// faster than the other normalization routines, but if v.length()
213
// is 0.0, the result is undefined.
214
//----------------------------------------------------------------
219
const Vec2 & normalize (); // modifies *this
220
const Vec2 & normalizeExc () throw (Iex::MathExc);
221
const Vec2 & normalizeNonNull ();
223
Vec2<T> normalized () const; // does not modify *this
224
Vec2<T> normalizedExc () const throw (Iex::MathExc);
225
Vec2<T> normalizedNonNull () const;
228
//--------------------------------------------------------
229
// Number of dimensions, i.e. number of elements in a Vec2
230
//--------------------------------------------------------
232
static unsigned int dimensions() {return 2;}
235
//-------------------------------------------------
236
// Limitations of type T (see also class limits<T>)
237
//-------------------------------------------------
239
static T baseTypeMin() {return limits<T>::min();}
240
static T baseTypeMax() {return limits<T>::max();}
241
static T baseTypeSmallest() {return limits<T>::smallest();}
242
static T baseTypeEpsilon() {return limits<T>::epsilon();}
245
//--------------------------------------------------------------
246
// Base type -- in templates, which accept a parameter, V, which
247
// could be either a Vec2<T> or a Vec3<T>, you can refer to T as
249
//--------------------------------------------------------------
255
template <class T> class Vec3
259
//-------------------
260
// Access to elements
261
//-------------------
265
T & operator [] (int i);
266
const T & operator [] (int i) const;
273
Vec3 (); // no initialization
274
explicit Vec3 (T a); // (a a a)
275
Vec3 (T a, T b, T c); // (a b c)
278
//---------------------------------
279
// Copy constructors and assignment
280
//---------------------------------
282
Vec3 (const Vec3 &v);
283
template <class S> Vec3 (const Vec3<S> &v);
285
const Vec3 & operator = (const Vec3 &v);
288
//----------------------
289
// Compatibility with Sb
290
//----------------------
293
void setValue (S a, S b, S c);
296
void setValue (const Vec3<S> &v);
299
void getValue (S &a, S &b, S &c) const;
302
void getValue (Vec3<S> &v) const;
305
const T * getValue() const;
313
bool operator == (const Vec3<S> &v) const;
316
bool operator != (const Vec3<S> &v) const;
318
//-----------------------------------------------------------------------
319
// Compare two vectors and test if they are "approximately equal":
321
// equalWithAbsError (v, e)
323
// Returns true if the coefficients of this and v are the same with
324
// an absolute error of no more than e, i.e., for all i
326
// abs (this[i] - v[i]) <= e
328
// equalWithRelError (v, e)
330
// Returns true if the coefficients of this and v are the same with
331
// a relative error of no more than e, i.e., for all i
333
// abs (this[i] - v[i]) <= e * abs (this[i])
334
//-----------------------------------------------------------------------
336
bool equalWithAbsError (const Vec3<T> &v, T e) const;
337
bool equalWithRelError (const Vec3<T> &v, T e) const;
343
T dot (const Vec3 &v) const;
344
T operator ^ (const Vec3 &v) const;
347
//---------------------------
348
// Right-handed cross product
349
//---------------------------
351
Vec3 cross (const Vec3 &v) const;
352
const Vec3 & operator %= (const Vec3 &v);
353
Vec3 operator % (const Vec3 &v) const;
356
//------------------------
357
// Component-wise addition
358
//------------------------
360
const Vec3 & operator += (const Vec3 &v);
361
Vec3 operator + (const Vec3 &v) const;
364
//---------------------------
365
// Component-wise subtraction
366
//---------------------------
368
const Vec3 & operator -= (const Vec3 &v);
369
Vec3 operator - (const Vec3 &v) const;
372
//------------------------------------
373
// Component-wise multiplication by -1
374
//------------------------------------
376
Vec3 operator - () const;
377
const Vec3 & negate ();
380
//------------------------------
381
// Component-wise multiplication
382
//------------------------------
384
const Vec3 & operator *= (const Vec3 &v);
385
const Vec3 & operator *= (T a);
386
Vec3 operator * (const Vec3 &v) const;
387
Vec3 operator * (T a) const;
390
//------------------------
391
// Component-wise division
392
//------------------------
394
const Vec3 & operator /= (const Vec3 &v);
395
const Vec3 & operator /= (T a);
396
Vec3 operator / (const Vec3 &v) const;
397
Vec3 operator / (T a) const;
400
//----------------------------------------------------------------
401
// Length and normalization: If v.length() is 0.0, v.normalize()
402
// and v.normalized() produce a null vector; v.normalizeExc() and
403
// v.normalizedExc() throw a NullVecExc.
404
// v.normalizeNonNull() and v.normalizedNonNull() are slightly
405
// faster than the other normalization routines, but if v.length()
406
// is 0.0, the result is undefined.
407
//----------------------------------------------------------------
412
const Vec3 & normalize (); // modifies *this
413
const Vec3 & normalizeExc () throw (Iex::MathExc);
414
const Vec3 & normalizeNonNull ();
416
Vec3<T> normalized () const; // does not modify *this
417
Vec3<T> normalizedExc () const throw (Iex::MathExc);
418
Vec3<T> normalizedNonNull () const;
421
//--------------------------------------------------------
422
// Number of dimensions, i.e. number of elements in a Vec3
423
//--------------------------------------------------------
425
static unsigned int dimensions() {return 3;}
428
//-------------------------------------------------
429
// Limitations of type T (see also class limits<T>)
430
//-------------------------------------------------
432
static T baseTypeMin() {return limits<T>::min();}
433
static T baseTypeMax() {return limits<T>::max();}
434
static T baseTypeSmallest() {return limits<T>::smallest();}
435
static T baseTypeEpsilon() {return limits<T>::epsilon();}
438
//--------------------------------------------------------------
439
// Base type -- in templates, which accept a parameter, V, which
440
// could be either a Vec2<T> or a Vec3<T>, you can refer to T as
442
//--------------------------------------------------------------
453
std::ostream & operator << (std::ostream &s, const Vec2<T> &v);
456
std::ostream & operator << (std::ostream &s, const Vec3<T> &v);
459
//----------------------------------------------------
460
// Reverse multiplication: S * Vec2<T> and S * Vec3<T>
461
//----------------------------------------------------
463
template <class T> Vec2<T> operator * (T a, const Vec2<T> &v);
464
template <class T> Vec3<T> operator * (T a, const Vec3<T> &v);
467
//-------------------------
468
// Typedefs for convenience
469
//-------------------------
471
typedef Vec2 <short> V2s;
472
typedef Vec2 <int> V2i;
473
typedef Vec2 <float> V2f;
474
typedef Vec2 <double> V2d;
475
typedef Vec3 <short> V3s;
476
typedef Vec3 <int> V3i;
477
typedef Vec3 <float> V3f;
478
typedef Vec3 <double> V3d;
481
//-------------------------------------------------------------------
482
// Specializations for Vec2<short>, Vec2<int>, Vec3<short>, Vec3<int>
483
//-------------------------------------------------------------------
488
Vec2<short>::length () const;
490
template <> const Vec2<short> &
491
Vec2<short>::normalize ();
493
template <> const Vec2<short> &
494
Vec2<short>::normalizeExc () throw (Iex::MathExc);
496
template <> const Vec2<short> &
497
Vec2<short>::normalizeNonNull ();
499
template <> Vec2<short>
500
Vec2<short>::normalized () const;
502
template <> Vec2<short>
503
Vec2<short>::normalizedExc () const throw (Iex::MathExc);
505
template <> Vec2<short>
506
Vec2<short>::normalizedNonNull () const;
512
Vec2<int>::length () const;
514
template <> const Vec2<int> &
515
Vec2<int>::normalize ();
517
template <> const Vec2<int> &
518
Vec2<int>::normalizeExc () throw (Iex::MathExc);
520
template <> const Vec2<int> &
521
Vec2<int>::normalizeNonNull ();
523
template <> Vec2<int>
524
Vec2<int>::normalized () const;
526
template <> Vec2<int>
527
Vec2<int>::normalizedExc () const throw (Iex::MathExc);
529
template <> Vec2<int>
530
Vec2<int>::normalizedNonNull () const;
536
Vec3<short>::length () const;
538
template <> const Vec3<short> &
539
Vec3<short>::normalize ();
541
template <> const Vec3<short> &
542
Vec3<short>::normalizeExc () throw (Iex::MathExc);
544
template <> const Vec3<short> &
545
Vec3<short>::normalizeNonNull ();
547
template <> Vec3<short>
548
Vec3<short>::normalized () const;
550
template <> Vec3<short>
551
Vec3<short>::normalizedExc () const throw (Iex::MathExc);
553
template <> Vec3<short>
554
Vec3<short>::normalizedNonNull () const;
560
Vec3<int>::length () const;
562
template <> const Vec3<int> &
563
Vec3<int>::normalize ();
565
template <> const Vec3<int> &
566
Vec3<int>::normalizeExc () throw (Iex::MathExc);
568
template <> const Vec3<int> &
569
Vec3<int>::normalizeNonNull ();
571
template <> Vec3<int>
572
Vec3<int>::normalized () const;
574
template <> Vec3<int>
575
Vec3<int>::normalizedExc () const throw (Iex::MathExc);
577
template <> Vec3<int>
578
Vec3<int>::normalizedNonNull () const;
581
//------------------------
582
// Implementation of Vec2:
583
//------------------------
587
Vec2<T>::operator [] (int i)
594
Vec2<T>::operator [] (int i) const
615
Vec2<T>::Vec2 (T a, T b)
623
Vec2<T>::Vec2 (const Vec2 &v)
632
Vec2<T>::Vec2 (const Vec2<S> &v)
639
inline const Vec2<T> &
640
Vec2<T>::operator = (const Vec2 &v)
650
Vec2<T>::setValue (S a, S b)
659
Vec2<T>::setValue (const Vec2<S> &v)
668
Vec2<T>::getValue (S &a, S &b) const
677
Vec2<T>::getValue (Vec2<S> &v) const
692
Vec2<T>::getValue() const
694
return (const T *) &x;
700
Vec2<T>::operator == (const Vec2<S> &v) const
702
return x == v.x && y == v.y;
708
Vec2<T>::operator != (const Vec2<S> &v) const
710
return x != v.x || y != v.y;
715
Vec2<T>::equalWithAbsError (const Vec2<T> &v, T e) const
717
for (int i = 0; i < 2; i++)
718
if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
726
Vec2<T>::equalWithRelError (const Vec2<T> &v, T e) const
728
for (int i = 0; i < 2; i++)
729
if (!Imath::equalWithRelError ((*this)[i], v[i], e))
737
Vec2<T>::dot (const Vec2 &v) const
739
return x * v.x + y * v.y;
744
Vec2<T>::operator ^ (const Vec2 &v) const
751
Vec2<T>::cross (const Vec2 &v) const
753
return x * v.y - y * v.x;
759
Vec2<T>::operator % (const Vec2 &v) const
761
return x * v.y - y * v.x;
765
inline const Vec2<T> &
766
Vec2<T>::operator += (const Vec2 &v)
775
Vec2<T>::operator + (const Vec2 &v) const
777
return Vec2 (x + v.x, y + v.y);
781
inline const Vec2<T> &
782
Vec2<T>::operator -= (const Vec2 &v)
791
Vec2<T>::operator - (const Vec2 &v) const
793
return Vec2 (x - v.x, y - v.y);
798
Vec2<T>::operator - () const
800
return Vec2 (-x, -y);
804
inline const Vec2<T> &
813
inline const Vec2<T> &
814
Vec2<T>::operator *= (const Vec2 &v)
822
inline const Vec2<T> &
823
Vec2<T>::operator *= (T a)
832
Vec2<T>::operator * (const Vec2 &v) const
834
return Vec2 (x * v.x, y * v.y);
839
Vec2<T>::operator * (T a) const
841
return Vec2 (x * a, y * a);
845
inline const Vec2<T> &
846
Vec2<T>::operator /= (const Vec2 &v)
854
inline const Vec2<T> &
855
Vec2<T>::operator /= (T a)
864
Vec2<T>::operator / (const Vec2 &v) const
866
return Vec2 (x / v.x, y / v.y);
871
Vec2<T>::operator / (T a) const
873
return Vec2 (x / a, y / a);
878
Vec2<T>::length () const
880
return Math<T>::sqrt (dot (*this));
885
Vec2<T>::length2 () const
892
Vec2<T>::normalize ()
907
Vec2<T>::normalizeExc () throw (Iex::MathExc)
912
throw NullVecExc ("Cannot normalize null vector.");
922
Vec2<T>::normalizeNonNull ()
932
Vec2<T>::normalized () const
939
return Vec2 (x / l, y / l);
944
Vec2<T>::normalizedExc () const throw (Iex::MathExc)
949
throw NullVecExc ("Cannot normalize null vector.");
951
return Vec2 (x / l, y / l);
957
Vec2<T>::normalizedNonNull () const
960
return Vec2 (x / l, y / l);
964
//-----------------------
965
// Implementation of Vec3
966
//-----------------------
970
Vec3<T>::operator [] (int i)
977
Vec3<T>::operator [] (int i) const
998
Vec3<T>::Vec3 (T a, T b, T c)
1007
Vec3<T>::Vec3 (const Vec3 &v)
1017
Vec3<T>::Vec3 (const Vec3<S> &v)
1025
inline const Vec3<T> &
1026
Vec3<T>::operator = (const Vec3 &v)
1037
Vec3<T>::setValue (S a, S b, S c)
1047
Vec3<T>::setValue (const Vec3<S> &v)
1057
Vec3<T>::getValue (S &a, S &b, S &c) const
1067
Vec3<T>::getValue (Vec3<S> &v) const
1083
Vec3<T>::getValue() const
1085
return (const T *) &x;
1091
Vec3<T>::operator == (const Vec3<S> &v) const
1093
return x == v.x && y == v.y && z == v.z;
1099
Vec3<T>::operator != (const Vec3<S> &v) const
1101
return x != v.x || y != v.y || z != v.z;
1106
Vec3<T>::equalWithAbsError (const Vec3<T> &v, T e) const
1108
for (int i = 0; i < 3; i++)
1109
if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
1117
Vec3<T>::equalWithRelError (const Vec3<T> &v, T e) const
1119
for (int i = 0; i < 3; i++)
1120
if (!Imath::equalWithRelError ((*this)[i], v[i], e))
1128
Vec3<T>::dot (const Vec3 &v) const
1130
return x * v.x + y * v.y + z * v.z;
1135
Vec3<T>::operator ^ (const Vec3 &v) const
1142
Vec3<T>::cross (const Vec3 &v) const
1144
return Vec3 (y * v.z - z * v.y,
1150
inline const Vec3<T> &
1151
Vec3<T>::operator %= (const Vec3 &v)
1153
T a = y * v.z - z * v.y;
1154
T b = z * v.x - x * v.z;
1155
T c = x * v.y - y * v.x;
1164
Vec3<T>::operator % (const Vec3 &v) const
1166
return Vec3 (y * v.z - z * v.y,
1172
inline const Vec3<T> &
1173
Vec3<T>::operator += (const Vec3 &v)
1183
Vec3<T>::operator + (const Vec3 &v) const
1185
return Vec3 (x + v.x, y + v.y, z + v.z);
1189
inline const Vec3<T> &
1190
Vec3<T>::operator -= (const Vec3 &v)
1200
Vec3<T>::operator - (const Vec3 &v) const
1202
return Vec3 (x - v.x, y - v.y, z - v.z);
1207
Vec3<T>::operator - () const
1209
return Vec3 (-x, -y, -z);
1213
inline const Vec3<T> &
1223
inline const Vec3<T> &
1224
Vec3<T>::operator *= (const Vec3 &v)
1233
inline const Vec3<T> &
1234
Vec3<T>::operator *= (T a)
1244
Vec3<T>::operator * (const Vec3 &v) const
1246
return Vec3 (x * v.x, y * v.y, z * v.z);
1251
Vec3<T>::operator * (T a) const
1253
return Vec3 (x * a, y * a, z * a);
1257
inline const Vec3<T> &
1258
Vec3<T>::operator /= (const Vec3 &v)
1267
inline const Vec3<T> &
1268
Vec3<T>::operator /= (T a)
1278
Vec3<T>::operator / (const Vec3 &v) const
1280
return Vec3 (x / v.x, y / v.y, z / v.z);
1285
Vec3<T>::operator / (T a) const
1287
return Vec3 (x / a, y / a, z / a);
1293
Vec3<T>::length () const
1295
return Math<T>::sqrt (dot (*this));
1300
Vec3<T>::length2 () const
1307
Vec3<T>::normalize ()
1323
Vec3<T>::normalizeExc () throw (Iex::MathExc)
1328
throw NullVecExc ("Cannot normalize null vector.");
1339
Vec3<T>::normalizeNonNull ()
1350
Vec3<T>::normalized () const
1355
return Vec3 (T (0));
1357
return Vec3 (x / l, y / l, z / l);
1362
Vec3<T>::normalizedExc () const throw (Iex::MathExc)
1367
throw NullVecExc ("Cannot normalize null vector.");
1369
return Vec3 (x / l, y / l, z / l);
1375
Vec3<T>::normalizedNonNull () const
1378
return Vec3 (x / l, y / l, z / l);
1382
//-----------------------------
1383
// Stream output implementation
1384
//-----------------------------
1388
operator << (std::ostream &s, const Vec2<T> &v)
1390
return s << '(' << v.x << ' ' << v.y << ')';
1395
operator << (std::ostream &s, const Vec3<T> &v)
1397
return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')';
1401
//-----------------------------------------
1402
// Implementation of reverse multiplication
1403
//-----------------------------------------
1407
operator * (T a, const Vec2<T> &v)
1409
return Vec2<T> (a * v.x, a * v.y);
1414
operator * (T a, const Vec3<T> &v)
1416
return Vec3<T> (a * v.x, a * v.y, a * v.z);
1420
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
1421
#pragma warning(default:4290)
1424
} // namespace Imath
1
///////////////////////////////////////////////////////////////////////////
3
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
6
// All rights reserved.
8
// Redistribution and use in source and binary forms, with or without
9
// modification, are permitted provided that the following conditions are
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
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.
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.
33
///////////////////////////////////////////////////////////////////////////
37
#ifndef INCLUDED_IMATHVEC_H
38
#define INCLUDED_IMATHVEC_H
40
//----------------------------------------------------
42
// 2D and 3D point/vector class templates!
44
//----------------------------------------------------
47
#include "ImathLimits.h"
48
#include "ImathMath.h"
52
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
53
// suppress exception specification warnings
54
#pragma warning(disable:4290)
61
template <class T> class Vec2
71
T & operator [] (int i);
72
const T & operator [] (int i) const;
79
Vec2 (); // no initialization
80
explicit Vec2 (T a); // (a a)
81
Vec2 (T a, T b); // (a b)
84
//---------------------------------
85
// Copy constructors and assignment
86
//---------------------------------
89
template <class S> Vec2 (const Vec2<S> &v);
91
const Vec2 & operator = (const Vec2 &v);
94
//----------------------
95
// Compatibility with Sb
96
//----------------------
99
void setValue (S a, S b);
102
void setValue (const Vec2<S> &v);
105
void getValue (S &a, S &b) const;
108
void getValue (Vec2<S> &v) const;
111
const T * getValue () const;
119
bool operator == (const Vec2<S> &v) const;
122
bool operator != (const Vec2<S> &v) const;
125
//-----------------------------------------------------------------------
126
// Compare two vectors and test if they are "approximately equal":
128
// equalWithAbsError (v, e)
130
// Returns true if the coefficients of this and v are the same with
131
// an absolute error of no more than e, i.e., for all i
133
// abs (this[i] - v[i]) <= e
135
// equalWithRelError (v, e)
137
// Returns true if the coefficients of this and v are the same with
138
// a relative error of no more than e, i.e., for all i
140
// abs (this[i] - v[i]) <= e * abs (this[i])
141
//-----------------------------------------------------------------------
143
bool equalWithAbsError (const Vec2<T> &v, T e) const;
144
bool equalWithRelError (const Vec2<T> &v, T e) const;
150
T dot (const Vec2 &v) const;
151
T operator ^ (const Vec2 &v) const;
154
//------------------------------------------------
155
// Right-handed cross product, i.e. z component of
156
// Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0)
157
//------------------------------------------------
159
T cross (const Vec2 &v) const;
160
T operator % (const Vec2 &v) const;
163
//------------------------
164
// Component-wise addition
165
//------------------------
167
const Vec2 & operator += (const Vec2 &v);
168
Vec2 operator + (const Vec2 &v) const;
171
//---------------------------
172
// Component-wise subtraction
173
//---------------------------
175
const Vec2 & operator -= (const Vec2 &v);
176
Vec2 operator - (const Vec2 &v) const;
179
//------------------------------------
180
// Component-wise multiplication by -1
181
//------------------------------------
183
Vec2 operator - () const;
184
const Vec2 & negate ();
187
//------------------------------
188
// Component-wise multiplication
189
//------------------------------
191
const Vec2 & operator *= (const Vec2 &v);
192
const Vec2 & operator *= (T a);
193
Vec2 operator * (const Vec2 &v) const;
194
Vec2 operator * (T a) const;
197
//------------------------
198
// Component-wise division
199
//------------------------
201
const Vec2 & operator /= (const Vec2 &v);
202
const Vec2 & operator /= (T a);
203
Vec2 operator / (const Vec2 &v) const;
204
Vec2 operator / (T a) const;
207
//----------------------------------------------------------------
208
// Length and normalization: If v.length() is 0.0, v.normalize()
209
// and v.normalized() produce a null vector; v.normalizeExc() and
210
// v.normalizedExc() throw a NullVecExc.
211
// v.normalizeNonNull() and v.normalizedNonNull() are slightly
212
// faster than the other normalization routines, but if v.length()
213
// is 0.0, the result is undefined.
214
//----------------------------------------------------------------
219
const Vec2 & normalize (); // modifies *this
220
const Vec2 & normalizeExc () throw (Iex::MathExc);
221
const Vec2 & normalizeNonNull ();
223
Vec2<T> normalized () const; // does not modify *this
224
Vec2<T> normalizedExc () const throw (Iex::MathExc);
225
Vec2<T> normalizedNonNull () const;
228
//--------------------------------------------------------
229
// Number of dimensions, i.e. number of elements in a Vec2
230
//--------------------------------------------------------
232
static unsigned int dimensions() {return 2;}
235
//-------------------------------------------------
236
// Limitations of type T (see also class limits<T>)
237
//-------------------------------------------------
239
static T baseTypeMin() {return limits<T>::min();}
240
static T baseTypeMax() {return limits<T>::max();}
241
static T baseTypeSmallest() {return limits<T>::smallest();}
242
static T baseTypeEpsilon() {return limits<T>::epsilon();}
245
//--------------------------------------------------------------
246
// Base type -- in templates, which accept a parameter, V, which
247
// could be either a Vec2<T> or a Vec3<T>, you can refer to T as
249
//--------------------------------------------------------------
255
template <class T> class Vec3
259
//-------------------
260
// Access to elements
261
//-------------------
265
T & operator [] (int i);
266
const T & operator [] (int i) const;
273
Vec3 (); // no initialization
274
explicit Vec3 (T a); // (a a a)
275
Vec3 (T a, T b, T c); // (a b c)
278
//---------------------------------
279
// Copy constructors and assignment
280
//---------------------------------
282
Vec3 (const Vec3 &v);
283
template <class S> Vec3 (const Vec3<S> &v);
285
const Vec3 & operator = (const Vec3 &v);
288
//----------------------
289
// Compatibility with Sb
290
//----------------------
293
void setValue (S a, S b, S c);
296
void setValue (const Vec3<S> &v);
299
void getValue (S &a, S &b, S &c) const;
302
void getValue (Vec3<S> &v) const;
305
const T * getValue() const;
313
bool operator == (const Vec3<S> &v) const;
316
bool operator != (const Vec3<S> &v) const;
318
//-----------------------------------------------------------------------
319
// Compare two vectors and test if they are "approximately equal":
321
// equalWithAbsError (v, e)
323
// Returns true if the coefficients of this and v are the same with
324
// an absolute error of no more than e, i.e., for all i
326
// abs (this[i] - v[i]) <= e
328
// equalWithRelError (v, e)
330
// Returns true if the coefficients of this and v are the same with
331
// a relative error of no more than e, i.e., for all i
333
// abs (this[i] - v[i]) <= e * abs (this[i])
334
//-----------------------------------------------------------------------
336
bool equalWithAbsError (const Vec3<T> &v, T e) const;
337
bool equalWithRelError (const Vec3<T> &v, T e) const;
343
T dot (const Vec3 &v) const;
344
T operator ^ (const Vec3 &v) const;
347
//---------------------------
348
// Right-handed cross product
349
//---------------------------
351
Vec3 cross (const Vec3 &v) const;
352
const Vec3 & operator %= (const Vec3 &v);
353
Vec3 operator % (const Vec3 &v) const;
356
//------------------------
357
// Component-wise addition
358
//------------------------
360
const Vec3 & operator += (const Vec3 &v);
361
Vec3 operator + (const Vec3 &v) const;
364
//---------------------------
365
// Component-wise subtraction
366
//---------------------------
368
const Vec3 & operator -= (const Vec3 &v);
369
Vec3 operator - (const Vec3 &v) const;
372
//------------------------------------
373
// Component-wise multiplication by -1
374
//------------------------------------
376
Vec3 operator - () const;
377
const Vec3 & negate ();
380
//------------------------------
381
// Component-wise multiplication
382
//------------------------------
384
const Vec3 & operator *= (const Vec3 &v);
385
const Vec3 & operator *= (T a);
386
Vec3 operator * (const Vec3 &v) const;
387
Vec3 operator * (T a) const;
390
//------------------------
391
// Component-wise division
392
//------------------------
394
const Vec3 & operator /= (const Vec3 &v);
395
const Vec3 & operator /= (T a);
396
Vec3 operator / (const Vec3 &v) const;
397
Vec3 operator / (T a) const;
400
//----------------------------------------------------------------
401
// Length and normalization: If v.length() is 0.0, v.normalize()
402
// and v.normalized() produce a null vector; v.normalizeExc() and
403
// v.normalizedExc() throw a NullVecExc.
404
// v.normalizeNonNull() and v.normalizedNonNull() are slightly
405
// faster than the other normalization routines, but if v.length()
406
// is 0.0, the result is undefined.
407
//----------------------------------------------------------------
412
const Vec3 & normalize (); // modifies *this
413
const Vec3 & normalizeExc () throw (Iex::MathExc);
414
const Vec3 & normalizeNonNull ();
416
Vec3<T> normalized () const; // does not modify *this
417
Vec3<T> normalizedExc () const throw (Iex::MathExc);
418
Vec3<T> normalizedNonNull () const;
421
//--------------------------------------------------------
422
// Number of dimensions, i.e. number of elements in a Vec3
423
//--------------------------------------------------------
425
static unsigned int dimensions() {return 3;}
428
//-------------------------------------------------
429
// Limitations of type T (see also class limits<T>)
430
//-------------------------------------------------
432
static T baseTypeMin() {return limits<T>::min();}
433
static T baseTypeMax() {return limits<T>::max();}
434
static T baseTypeSmallest() {return limits<T>::smallest();}
435
static T baseTypeEpsilon() {return limits<T>::epsilon();}
438
//--------------------------------------------------------------
439
// Base type -- in templates, which accept a parameter, V, which
440
// could be either a Vec2<T> or a Vec3<T>, you can refer to T as
442
//--------------------------------------------------------------
453
std::ostream & operator << (std::ostream &s, const Vec2<T> &v);
456
std::ostream & operator << (std::ostream &s, const Vec3<T> &v);
459
//----------------------------------------------------
460
// Reverse multiplication: S * Vec2<T> and S * Vec3<T>
461
//----------------------------------------------------
463
template <class T> Vec2<T> operator * (T a, const Vec2<T> &v);
464
template <class T> Vec3<T> operator * (T a, const Vec3<T> &v);
467
//-------------------------
468
// Typedefs for convenience
469
//-------------------------
471
typedef Vec2 <short> V2s;
472
typedef Vec2 <int> V2i;
473
typedef Vec2 <float> V2f;
474
typedef Vec2 <double> V2d;
475
typedef Vec3 <short> V3s;
476
typedef Vec3 <int> V3i;
477
typedef Vec3 <float> V3f;
478
typedef Vec3 <double> V3d;
481
//-------------------------------------------------------------------
482
// Specializations for Vec2<short>, Vec2<int>, Vec3<short>, Vec3<int>
483
//-------------------------------------------------------------------
488
Vec2<short>::length () const;
490
template <> const Vec2<short> &
491
Vec2<short>::normalize ();
493
template <> const Vec2<short> &
494
Vec2<short>::normalizeExc () throw (Iex::MathExc);
496
template <> const Vec2<short> &
497
Vec2<short>::normalizeNonNull ();
499
template <> Vec2<short>
500
Vec2<short>::normalized () const;
502
template <> Vec2<short>
503
Vec2<short>::normalizedExc () const throw (Iex::MathExc);
505
template <> Vec2<short>
506
Vec2<short>::normalizedNonNull () const;
512
Vec2<int>::length () const;
514
template <> const Vec2<int> &
515
Vec2<int>::normalize ();
517
template <> const Vec2<int> &
518
Vec2<int>::normalizeExc () throw (Iex::MathExc);
520
template <> const Vec2<int> &
521
Vec2<int>::normalizeNonNull ();
523
template <> Vec2<int>
524
Vec2<int>::normalized () const;
526
template <> Vec2<int>
527
Vec2<int>::normalizedExc () const throw (Iex::MathExc);
529
template <> Vec2<int>
530
Vec2<int>::normalizedNonNull () const;
536
Vec3<short>::length () const;
538
template <> const Vec3<short> &
539
Vec3<short>::normalize ();
541
template <> const Vec3<short> &
542
Vec3<short>::normalizeExc () throw (Iex::MathExc);
544
template <> const Vec3<short> &
545
Vec3<short>::normalizeNonNull ();
547
template <> Vec3<short>
548
Vec3<short>::normalized () const;
550
template <> Vec3<short>
551
Vec3<short>::normalizedExc () const throw (Iex::MathExc);
553
template <> Vec3<short>
554
Vec3<short>::normalizedNonNull () const;
560
Vec3<int>::length () const;
562
template <> const Vec3<int> &
563
Vec3<int>::normalize ();
565
template <> const Vec3<int> &
566
Vec3<int>::normalizeExc () throw (Iex::MathExc);
568
template <> const Vec3<int> &
569
Vec3<int>::normalizeNonNull ();
571
template <> Vec3<int>
572
Vec3<int>::normalized () const;
574
template <> Vec3<int>
575
Vec3<int>::normalizedExc () const throw (Iex::MathExc);
577
template <> Vec3<int>
578
Vec3<int>::normalizedNonNull () const;
581
//------------------------
582
// Implementation of Vec2:
583
//------------------------
587
Vec2<T>::operator [] (int i)
594
Vec2<T>::operator [] (int i) const
615
Vec2<T>::Vec2 (T a, T b)
623
Vec2<T>::Vec2 (const Vec2 &v)
632
Vec2<T>::Vec2 (const Vec2<S> &v)
639
inline const Vec2<T> &
640
Vec2<T>::operator = (const Vec2 &v)
650
Vec2<T>::setValue (S a, S b)
659
Vec2<T>::setValue (const Vec2<S> &v)
668
Vec2<T>::getValue (S &a, S &b) const
677
Vec2<T>::getValue (Vec2<S> &v) const
692
Vec2<T>::getValue() const
694
return (const T *) &x;
700
Vec2<T>::operator == (const Vec2<S> &v) const
702
return x == v.x && y == v.y;
708
Vec2<T>::operator != (const Vec2<S> &v) const
710
return x != v.x || y != v.y;
715
Vec2<T>::equalWithAbsError (const Vec2<T> &v, T e) const
717
for (int i = 0; i < 2; i++)
718
if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
726
Vec2<T>::equalWithRelError (const Vec2<T> &v, T e) const
728
for (int i = 0; i < 2; i++)
729
if (!Imath::equalWithRelError ((*this)[i], v[i], e))
737
Vec2<T>::dot (const Vec2 &v) const
739
return x * v.x + y * v.y;
744
Vec2<T>::operator ^ (const Vec2 &v) const
751
Vec2<T>::cross (const Vec2 &v) const
753
return x * v.y - y * v.x;
759
Vec2<T>::operator % (const Vec2 &v) const
761
return x * v.y - y * v.x;
765
inline const Vec2<T> &
766
Vec2<T>::operator += (const Vec2 &v)
775
Vec2<T>::operator + (const Vec2 &v) const
777
return Vec2 (x + v.x, y + v.y);
781
inline const Vec2<T> &
782
Vec2<T>::operator -= (const Vec2 &v)
791
Vec2<T>::operator - (const Vec2 &v) const
793
return Vec2 (x - v.x, y - v.y);
798
Vec2<T>::operator - () const
800
return Vec2 (-x, -y);
804
inline const Vec2<T> &
813
inline const Vec2<T> &
814
Vec2<T>::operator *= (const Vec2 &v)
822
inline const Vec2<T> &
823
Vec2<T>::operator *= (T a)
832
Vec2<T>::operator * (const Vec2 &v) const
834
return Vec2 (x * v.x, y * v.y);
839
Vec2<T>::operator * (T a) const
841
return Vec2 (x * a, y * a);
845
inline const Vec2<T> &
846
Vec2<T>::operator /= (const Vec2 &v)
854
inline const Vec2<T> &
855
Vec2<T>::operator /= (T a)
864
Vec2<T>::operator / (const Vec2 &v) const
866
return Vec2 (x / v.x, y / v.y);
871
Vec2<T>::operator / (T a) const
873
return Vec2 (x / a, y / a);
878
Vec2<T>::length () const
880
return Math<T>::sqrt (dot (*this));
885
Vec2<T>::length2 () const
892
Vec2<T>::normalize ()
907
Vec2<T>::normalizeExc () throw (Iex::MathExc)
912
throw NullVecExc ("Cannot normalize null vector.");
922
Vec2<T>::normalizeNonNull ()
932
Vec2<T>::normalized () const
939
return Vec2 (x / l, y / l);
944
Vec2<T>::normalizedExc () const throw (Iex::MathExc)
949
throw NullVecExc ("Cannot normalize null vector.");
951
return Vec2 (x / l, y / l);
957
Vec2<T>::normalizedNonNull () const
960
return Vec2 (x / l, y / l);
964
//-----------------------
965
// Implementation of Vec3
966
//-----------------------
970
Vec3<T>::operator [] (int i)
977
Vec3<T>::operator [] (int i) const
998
Vec3<T>::Vec3 (T a, T b, T c)
1007
Vec3<T>::Vec3 (const Vec3 &v)
1017
Vec3<T>::Vec3 (const Vec3<S> &v)
1025
inline const Vec3<T> &
1026
Vec3<T>::operator = (const Vec3 &v)
1037
Vec3<T>::setValue (S a, S b, S c)
1047
Vec3<T>::setValue (const Vec3<S> &v)
1057
Vec3<T>::getValue (S &a, S &b, S &c) const
1067
Vec3<T>::getValue (Vec3<S> &v) const
1083
Vec3<T>::getValue() const
1085
return (const T *) &x;
1091
Vec3<T>::operator == (const Vec3<S> &v) const
1093
return x == v.x && y == v.y && z == v.z;
1099
Vec3<T>::operator != (const Vec3<S> &v) const
1101
return x != v.x || y != v.y || z != v.z;
1106
Vec3<T>::equalWithAbsError (const Vec3<T> &v, T e) const
1108
for (int i = 0; i < 3; i++)
1109
if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
1117
Vec3<T>::equalWithRelError (const Vec3<T> &v, T e) const
1119
for (int i = 0; i < 3; i++)
1120
if (!Imath::equalWithRelError ((*this)[i], v[i], e))
1128
Vec3<T>::dot (const Vec3 &v) const
1130
return x * v.x + y * v.y + z * v.z;
1135
Vec3<T>::operator ^ (const Vec3 &v) const
1142
Vec3<T>::cross (const Vec3 &v) const
1144
return Vec3 (y * v.z - z * v.y,
1150
inline const Vec3<T> &
1151
Vec3<T>::operator %= (const Vec3 &v)
1153
T a = y * v.z - z * v.y;
1154
T b = z * v.x - x * v.z;
1155
T c = x * v.y - y * v.x;
1164
Vec3<T>::operator % (const Vec3 &v) const
1166
return Vec3 (y * v.z - z * v.y,
1172
inline const Vec3<T> &
1173
Vec3<T>::operator += (const Vec3 &v)
1183
Vec3<T>::operator + (const Vec3 &v) const
1185
return Vec3 (x + v.x, y + v.y, z + v.z);
1189
inline const Vec3<T> &
1190
Vec3<T>::operator -= (const Vec3 &v)
1200
Vec3<T>::operator - (const Vec3 &v) const
1202
return Vec3 (x - v.x, y - v.y, z - v.z);
1207
Vec3<T>::operator - () const
1209
return Vec3 (-x, -y, -z);
1213
inline const Vec3<T> &
1223
inline const Vec3<T> &
1224
Vec3<T>::operator *= (const Vec3 &v)
1233
inline const Vec3<T> &
1234
Vec3<T>::operator *= (T a)
1244
Vec3<T>::operator * (const Vec3 &v) const
1246
return Vec3 (x * v.x, y * v.y, z * v.z);
1251
Vec3<T>::operator * (T a) const
1253
return Vec3 (x * a, y * a, z * a);
1257
inline const Vec3<T> &
1258
Vec3<T>::operator /= (const Vec3 &v)
1267
inline const Vec3<T> &
1268
Vec3<T>::operator /= (T a)
1278
Vec3<T>::operator / (const Vec3 &v) const
1280
return Vec3 (x / v.x, y / v.y, z / v.z);
1285
Vec3<T>::operator / (T a) const
1287
return Vec3 (x / a, y / a, z / a);
1293
Vec3<T>::length () const
1295
return Math<T>::sqrt (dot (*this));
1300
Vec3<T>::length2 () const
1307
Vec3<T>::normalize ()
1323
Vec3<T>::normalizeExc () throw (Iex::MathExc)
1328
throw NullVecExc ("Cannot normalize null vector.");
1339
Vec3<T>::normalizeNonNull ()
1350
Vec3<T>::normalized () const
1355
return Vec3 (T (0));
1357
return Vec3 (x / l, y / l, z / l);
1362
Vec3<T>::normalizedExc () const throw (Iex::MathExc)
1367
throw NullVecExc ("Cannot normalize null vector.");
1369
return Vec3 (x / l, y / l, z / l);
1375
Vec3<T>::normalizedNonNull () const
1378
return Vec3 (x / l, y / l, z / l);
1382
//-----------------------------
1383
// Stream output implementation
1384
//-----------------------------
1388
operator << (std::ostream &s, const Vec2<T> &v)
1390
return s << '(' << v.x << ' ' << v.y << ')';
1395
operator << (std::ostream &s, const Vec3<T> &v)
1397
return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')';
1401
//-----------------------------------------
1402
// Implementation of reverse multiplication
1403
//-----------------------------------------
1407
operator * (T a, const Vec2<T> &v)
1409
return Vec2<T> (a * v.x, a * v.y);
1414
operator * (T a, const Vec3<T> &v)
1416
return Vec3<T> (a * v.x, a * v.y, a * v.z);
1420
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
1421
#pragma warning(default:4290)
1424
} // namespace Imath