Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1426 lines
28 KiB
1426 lines
28 KiB
/////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas |
|
// Digital Ltd. LLC |
|
// |
|
// All rights reserved. |
|
// |
|
// Redistribution and use in source and binary forms, with or without |
|
// modification, are permitted provided that the following conditions are |
|
// met: |
|
// * Redistributions of source code must retain the above copyright |
|
// notice, this list of conditions and the following disclaimer. |
|
// * Redistributions in binary form must reproduce the above |
|
// copyright notice, this list of conditions and the following disclaimer |
|
// in the documentation and/or other materials provided with the |
|
// distribution. |
|
// * Neither the name of Industrial Light & Magic nor the names of |
|
// its contributors may be used to endorse or promote products derived |
|
// from this software without specific prior written permission. |
|
// |
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
// |
|
/////////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
|
|
#ifndef INCLUDED_IMATHVEC_H |
|
#define INCLUDED_IMATHVEC_H |
|
|
|
//---------------------------------------------------- |
|
// |
|
// 2D and 3D point/vector class templates! |
|
// |
|
//---------------------------------------------------- |
|
|
|
#include "ImathExc.h" |
|
#include "ImathLimits.h" |
|
#include "ImathMath.h" |
|
|
|
#include <iostream> |
|
|
|
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER |
|
// suppress exception specification warnings |
|
#pragma warning(disable:4290) |
|
#endif |
|
|
|
|
|
namespace Imath { |
|
|
|
|
|
template <class T> class Vec2 |
|
{ |
|
public: |
|
|
|
//------------------- |
|
// Access to elements |
|
//------------------- |
|
|
|
T x, y; |
|
|
|
T & operator [] (int i); |
|
const T & operator [] (int i) const; |
|
|
|
|
|
//------------- |
|
// Constructors |
|
//------------- |
|
|
|
Vec2 (); // no initialization |
|
explicit Vec2 (T a); // (a a) |
|
Vec2 (T a, T b); // (a b) |
|
|
|
|
|
//--------------------------------- |
|
// Copy constructors and assignment |
|
//--------------------------------- |
|
|
|
Vec2 (const Vec2 &v); |
|
template <class S> Vec2 (const Vec2<S> &v); |
|
|
|
const Vec2 & operator = (const Vec2 &v); |
|
|
|
|
|
//---------------------- |
|
// Compatibility with Sb |
|
//---------------------- |
|
|
|
template <class S> |
|
void setValue (S a, S b); |
|
|
|
template <class S> |
|
void setValue (const Vec2<S> &v); |
|
|
|
template <class S> |
|
void getValue (S &a, S &b) const; |
|
|
|
template <class S> |
|
void getValue (Vec2<S> &v) const; |
|
|
|
T * getValue (); |
|
const T * getValue () const; |
|
|
|
|
|
//--------- |
|
// Equality |
|
//--------- |
|
|
|
template <class S> |
|
bool operator == (const Vec2<S> &v) const; |
|
|
|
template <class S> |
|
bool operator != (const Vec2<S> &v) const; |
|
|
|
|
|
//----------------------------------------------------------------------- |
|
// Compare two vectors and test if they are "approximately equal": |
|
// |
|
// equalWithAbsError (v, e) |
|
// |
|
// Returns true if the coefficients of this and v are the same with |
|
// an absolute error of no more than e, i.e., for all i |
|
// |
|
// abs (this[i] - v[i]) <= e |
|
// |
|
// equalWithRelError (v, e) |
|
// |
|
// Returns true if the coefficients of this and v are the same with |
|
// a relative error of no more than e, i.e., for all i |
|
// |
|
// abs (this[i] - v[i]) <= e * abs (this[i]) |
|
//----------------------------------------------------------------------- |
|
|
|
bool equalWithAbsError (const Vec2<T> &v, T e) const; |
|
bool equalWithRelError (const Vec2<T> &v, T e) const; |
|
|
|
//------------ |
|
// Dot product |
|
//------------ |
|
|
|
T dot (const Vec2 &v) const; |
|
T operator ^ (const Vec2 &v) const; |
|
|
|
|
|
//------------------------------------------------ |
|
// Right-handed cross product, i.e. z component of |
|
// Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0) |
|
//------------------------------------------------ |
|
|
|
T cross (const Vec2 &v) const; |
|
T operator % (const Vec2 &v) const; |
|
|
|
|
|
//------------------------ |
|
// Component-wise addition |
|
//------------------------ |
|
|
|
const Vec2 & operator += (const Vec2 &v); |
|
Vec2 operator + (const Vec2 &v) const; |
|
|
|
|
|
//--------------------------- |
|
// Component-wise subtraction |
|
//--------------------------- |
|
|
|
const Vec2 & operator -= (const Vec2 &v); |
|
Vec2 operator - (const Vec2 &v) const; |
|
|
|
|
|
//------------------------------------ |
|
// Component-wise multiplication by -1 |
|
//------------------------------------ |
|
|
|
Vec2 operator - () const; |
|
const Vec2 & negate (); |
|
|
|
|
|
//------------------------------ |
|
// Component-wise multiplication |
|
//------------------------------ |
|
|
|
const Vec2 & operator *= (const Vec2 &v); |
|
const Vec2 & operator *= (T a); |
|
Vec2 operator * (const Vec2 &v) const; |
|
Vec2 operator * (T a) const; |
|
|
|
|
|
//------------------------ |
|
// Component-wise division |
|
//------------------------ |
|
|
|
const Vec2 & operator /= (const Vec2 &v); |
|
const Vec2 & operator /= (T a); |
|
Vec2 operator / (const Vec2 &v) const; |
|
Vec2 operator / (T a) const; |
|
|
|
|
|
//---------------------------------------------------------------- |
|
// Length and normalization: If v.length() is 0.0, v.normalize() |
|
// and v.normalized() produce a null vector; v.normalizeExc() and |
|
// v.normalizedExc() throw a NullVecExc. |
|
// v.normalizeNonNull() and v.normalizedNonNull() are slightly |
|
// faster than the other normalization routines, but if v.length() |
|
// is 0.0, the result is undefined. |
|
//---------------------------------------------------------------- |
|
|
|
T length () const; |
|
T length2 () const; |
|
|
|
const Vec2 & normalize (); // modifies *this |
|
const Vec2 & normalizeExc () throw (Iex::MathExc); |
|
const Vec2 & normalizeNonNull (); |
|
|
|
Vec2<T> normalized () const; // does not modify *this |
|
Vec2<T> normalizedExc () const throw (Iex::MathExc); |
|
Vec2<T> normalizedNonNull () const; |
|
|
|
|
|
//-------------------------------------------------------- |
|
// Number of dimensions, i.e. number of elements in a Vec2 |
|
//-------------------------------------------------------- |
|
|
|
static unsigned int dimensions() {return 2;} |
|
|
|
|
|
//------------------------------------------------- |
|
// Limitations of type T (see also class limits<T>) |
|
//------------------------------------------------- |
|
|
|
static T baseTypeMin() {return limits<T>::min();} |
|
static T baseTypeMax() {return limits<T>::max();} |
|
static T baseTypeSmallest() {return limits<T>::smallest();} |
|
static T baseTypeEpsilon() {return limits<T>::epsilon();} |
|
|
|
|
|
//-------------------------------------------------------------- |
|
// Base type -- in templates, which accept a parameter, V, which |
|
// could be either a Vec2<T> or a Vec3<T>, you can refer to T as |
|
// V::BaseType |
|
//-------------------------------------------------------------- |
|
|
|
typedef T BaseType; |
|
}; |
|
|
|
|
|
template <class T> class Vec3 |
|
{ |
|
public: |
|
|
|
//------------------- |
|
// Access to elements |
|
//------------------- |
|
|
|
T x, y, z; |
|
|
|
T & operator [] (int i); |
|
const T & operator [] (int i) const; |
|
|
|
|
|
//------------- |
|
// Constructors |
|
//------------- |
|
|
|
Vec3 (); // no initialization |
|
explicit Vec3 (T a); // (a a a) |
|
Vec3 (T a, T b, T c); // (a b c) |
|
|
|
|
|
//--------------------------------- |
|
// Copy constructors and assignment |
|
//--------------------------------- |
|
|
|
Vec3 (const Vec3 &v); |
|
template <class S> Vec3 (const Vec3<S> &v); |
|
|
|
const Vec3 & operator = (const Vec3 &v); |
|
|
|
|
|
//---------------------- |
|
// Compatibility with Sb |
|
//---------------------- |
|
|
|
template <class S> |
|
void setValue (S a, S b, S c); |
|
|
|
template <class S> |
|
void setValue (const Vec3<S> &v); |
|
|
|
template <class S> |
|
void getValue (S &a, S &b, S &c) const; |
|
|
|
template <class S> |
|
void getValue (Vec3<S> &v) const; |
|
|
|
T * getValue(); |
|
const T * getValue() const; |
|
|
|
|
|
//--------- |
|
// Equality |
|
//--------- |
|
|
|
template <class S> |
|
bool operator == (const Vec3<S> &v) const; |
|
|
|
template <class S> |
|
bool operator != (const Vec3<S> &v) const; |
|
|
|
//----------------------------------------------------------------------- |
|
// Compare two vectors and test if they are "approximately equal": |
|
// |
|
// equalWithAbsError (v, e) |
|
// |
|
// Returns true if the coefficients of this and v are the same with |
|
// an absolute error of no more than e, i.e., for all i |
|
// |
|
// abs (this[i] - v[i]) <= e |
|
// |
|
// equalWithRelError (v, e) |
|
// |
|
// Returns true if the coefficients of this and v are the same with |
|
// a relative error of no more than e, i.e., for all i |
|
// |
|
// abs (this[i] - v[i]) <= e * abs (this[i]) |
|
//----------------------------------------------------------------------- |
|
|
|
bool equalWithAbsError (const Vec3<T> &v, T e) const; |
|
bool equalWithRelError (const Vec3<T> &v, T e) const; |
|
|
|
//------------ |
|
// Dot product |
|
//------------ |
|
|
|
T dot (const Vec3 &v) const; |
|
T operator ^ (const Vec3 &v) const; |
|
|
|
|
|
//--------------------------- |
|
// Right-handed cross product |
|
//--------------------------- |
|
|
|
Vec3 cross (const Vec3 &v) const; |
|
const Vec3 & operator %= (const Vec3 &v); |
|
Vec3 operator % (const Vec3 &v) const; |
|
|
|
|
|
//------------------------ |
|
// Component-wise addition |
|
//------------------------ |
|
|
|
const Vec3 & operator += (const Vec3 &v); |
|
Vec3 operator + (const Vec3 &v) const; |
|
|
|
|
|
//--------------------------- |
|
// Component-wise subtraction |
|
//--------------------------- |
|
|
|
const Vec3 & operator -= (const Vec3 &v); |
|
Vec3 operator - (const Vec3 &v) const; |
|
|
|
|
|
//------------------------------------ |
|
// Component-wise multiplication by -1 |
|
//------------------------------------ |
|
|
|
Vec3 operator - () const; |
|
const Vec3 & negate (); |
|
|
|
|
|
//------------------------------ |
|
// Component-wise multiplication |
|
//------------------------------ |
|
|
|
const Vec3 & operator *= (const Vec3 &v); |
|
const Vec3 & operator *= (T a); |
|
Vec3 operator * (const Vec3 &v) const; |
|
Vec3 operator * (T a) const; |
|
|
|
|
|
//------------------------ |
|
// Component-wise division |
|
//------------------------ |
|
|
|
const Vec3 & operator /= (const Vec3 &v); |
|
const Vec3 & operator /= (T a); |
|
Vec3 operator / (const Vec3 &v) const; |
|
Vec3 operator / (T a) const; |
|
|
|
|
|
//---------------------------------------------------------------- |
|
// Length and normalization: If v.length() is 0.0, v.normalize() |
|
// and v.normalized() produce a null vector; v.normalizeExc() and |
|
// v.normalizedExc() throw a NullVecExc. |
|
// v.normalizeNonNull() and v.normalizedNonNull() are slightly |
|
// faster than the other normalization routines, but if v.length() |
|
// is 0.0, the result is undefined. |
|
//---------------------------------------------------------------- |
|
|
|
T length () const; |
|
T length2 () const; |
|
|
|
const Vec3 & normalize (); // modifies *this |
|
const Vec3 & normalizeExc () throw (Iex::MathExc); |
|
const Vec3 & normalizeNonNull (); |
|
|
|
Vec3<T> normalized () const; // does not modify *this |
|
Vec3<T> normalizedExc () const throw (Iex::MathExc); |
|
Vec3<T> normalizedNonNull () const; |
|
|
|
|
|
//-------------------------------------------------------- |
|
// Number of dimensions, i.e. number of elements in a Vec3 |
|
//-------------------------------------------------------- |
|
|
|
static unsigned int dimensions() {return 3;} |
|
|
|
|
|
//------------------------------------------------- |
|
// Limitations of type T (see also class limits<T>) |
|
//------------------------------------------------- |
|
|
|
static T baseTypeMin() {return limits<T>::min();} |
|
static T baseTypeMax() {return limits<T>::max();} |
|
static T baseTypeSmallest() {return limits<T>::smallest();} |
|
static T baseTypeEpsilon() {return limits<T>::epsilon();} |
|
|
|
|
|
//-------------------------------------------------------------- |
|
// Base type -- in templates, which accept a parameter, V, which |
|
// could be either a Vec2<T> or a Vec3<T>, you can refer to T as |
|
// V::BaseType |
|
//-------------------------------------------------------------- |
|
|
|
typedef T BaseType; |
|
}; |
|
|
|
|
|
//-------------- |
|
// Stream output |
|
//-------------- |
|
|
|
template <class T> |
|
std::ostream & operator << (std::ostream &s, const Vec2<T> &v); |
|
|
|
template <class T> |
|
std::ostream & operator << (std::ostream &s, const Vec3<T> &v); |
|
|
|
|
|
//---------------------------------------------------- |
|
// Reverse multiplication: S * Vec2<T> and S * Vec3<T> |
|
//---------------------------------------------------- |
|
|
|
template <class T> Vec2<T> operator * (T a, const Vec2<T> &v); |
|
template <class T> Vec3<T> operator * (T a, const Vec3<T> &v); |
|
|
|
|
|
//------------------------- |
|
// Typedefs for convenience |
|
//------------------------- |
|
|
|
typedef Vec2 <short> V2s; |
|
typedef Vec2 <int> V2i; |
|
typedef Vec2 <float> V2f; |
|
typedef Vec2 <double> V2d; |
|
typedef Vec3 <short> V3s; |
|
typedef Vec3 <int> V3i; |
|
typedef Vec3 <float> V3f; |
|
typedef Vec3 <double> V3d; |
|
|
|
|
|
//------------------------------------------------------------------- |
|
// Specializations for Vec2<short>, Vec2<int>, Vec3<short>, Vec3<int> |
|
//------------------------------------------------------------------- |
|
|
|
// Vec2<short> |
|
|
|
template <> short |
|
Vec2<short>::length () const; |
|
|
|
template <> const Vec2<short> & |
|
Vec2<short>::normalize (); |
|
|
|
template <> const Vec2<short> & |
|
Vec2<short>::normalizeExc () throw (Iex::MathExc); |
|
|
|
template <> const Vec2<short> & |
|
Vec2<short>::normalizeNonNull (); |
|
|
|
template <> Vec2<short> |
|
Vec2<short>::normalized () const; |
|
|
|
template <> Vec2<short> |
|
Vec2<short>::normalizedExc () const throw (Iex::MathExc); |
|
|
|
template <> Vec2<short> |
|
Vec2<short>::normalizedNonNull () const; |
|
|
|
|
|
// Vec2<int> |
|
|
|
template <> int |
|
Vec2<int>::length () const; |
|
|
|
template <> const Vec2<int> & |
|
Vec2<int>::normalize (); |
|
|
|
template <> const Vec2<int> & |
|
Vec2<int>::normalizeExc () throw (Iex::MathExc); |
|
|
|
template <> const Vec2<int> & |
|
Vec2<int>::normalizeNonNull (); |
|
|
|
template <> Vec2<int> |
|
Vec2<int>::normalized () const; |
|
|
|
template <> Vec2<int> |
|
Vec2<int>::normalizedExc () const throw (Iex::MathExc); |
|
|
|
template <> Vec2<int> |
|
Vec2<int>::normalizedNonNull () const; |
|
|
|
|
|
// Vec3<short> |
|
|
|
template <> short |
|
Vec3<short>::length () const; |
|
|
|
template <> const Vec3<short> & |
|
Vec3<short>::normalize (); |
|
|
|
template <> const Vec3<short> & |
|
Vec3<short>::normalizeExc () throw (Iex::MathExc); |
|
|
|
template <> const Vec3<short> & |
|
Vec3<short>::normalizeNonNull (); |
|
|
|
template <> Vec3<short> |
|
Vec3<short>::normalized () const; |
|
|
|
template <> Vec3<short> |
|
Vec3<short>::normalizedExc () const throw (Iex::MathExc); |
|
|
|
template <> Vec3<short> |
|
Vec3<short>::normalizedNonNull () const; |
|
|
|
|
|
// Vec3<int> |
|
|
|
template <> int |
|
Vec3<int>::length () const; |
|
|
|
template <> const Vec3<int> & |
|
Vec3<int>::normalize (); |
|
|
|
template <> const Vec3<int> & |
|
Vec3<int>::normalizeExc () throw (Iex::MathExc); |
|
|
|
template <> const Vec3<int> & |
|
Vec3<int>::normalizeNonNull (); |
|
|
|
template <> Vec3<int> |
|
Vec3<int>::normalized () const; |
|
|
|
template <> Vec3<int> |
|
Vec3<int>::normalizedExc () const throw (Iex::MathExc); |
|
|
|
template <> Vec3<int> |
|
Vec3<int>::normalizedNonNull () const; |
|
|
|
|
|
//------------------------ |
|
// Implementation of Vec2: |
|
//------------------------ |
|
|
|
template <class T> |
|
inline T & |
|
Vec2<T>::operator [] (int i) |
|
{ |
|
return (&x)[i]; |
|
} |
|
|
|
template <class T> |
|
inline const T & |
|
Vec2<T>::operator [] (int i) const |
|
{ |
|
return (&x)[i]; |
|
} |
|
|
|
template <class T> |
|
inline |
|
Vec2<T>::Vec2 () |
|
{ |
|
// empty |
|
} |
|
|
|
template <class T> |
|
inline |
|
Vec2<T>::Vec2 (T a) |
|
{ |
|
x = y = a; |
|
} |
|
|
|
template <class T> |
|
inline |
|
Vec2<T>::Vec2 (T a, T b) |
|
{ |
|
x = a; |
|
y = b; |
|
} |
|
|
|
template <class T> |
|
inline |
|
Vec2<T>::Vec2 (const Vec2 &v) |
|
{ |
|
x = v.x; |
|
y = v.y; |
|
} |
|
|
|
template <class T> |
|
template <class S> |
|
inline |
|
Vec2<T>::Vec2 (const Vec2<S> &v) |
|
{ |
|
x = T (v.x); |
|
y = T (v.y); |
|
} |
|
|
|
template <class T> |
|
inline const Vec2<T> & |
|
Vec2<T>::operator = (const Vec2 &v) |
|
{ |
|
x = v.x; |
|
y = v.y; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
template <class S> |
|
inline void |
|
Vec2<T>::setValue (S a, S b) |
|
{ |
|
x = T (a); |
|
y = T (b); |
|
} |
|
|
|
template <class T> |
|
template <class S> |
|
inline void |
|
Vec2<T>::setValue (const Vec2<S> &v) |
|
{ |
|
x = T (v.x); |
|
y = T (v.y); |
|
} |
|
|
|
template <class T> |
|
template <class S> |
|
inline void |
|
Vec2<T>::getValue (S &a, S &b) const |
|
{ |
|
a = S (x); |
|
b = S (y); |
|
} |
|
|
|
template <class T> |
|
template <class S> |
|
inline void |
|
Vec2<T>::getValue (Vec2<S> &v) const |
|
{ |
|
v.x = S (x); |
|
v.y = S (y); |
|
} |
|
|
|
template <class T> |
|
inline T * |
|
Vec2<T>::getValue() |
|
{ |
|
return (T *) &x; |
|
} |
|
|
|
template <class T> |
|
inline const T * |
|
Vec2<T>::getValue() const |
|
{ |
|
return (const T *) &x; |
|
} |
|
|
|
template <class T> |
|
template <class S> |
|
inline bool |
|
Vec2<T>::operator == (const Vec2<S> &v) const |
|
{ |
|
return x == v.x && y == v.y; |
|
} |
|
|
|
template <class T> |
|
template <class S> |
|
inline bool |
|
Vec2<T>::operator != (const Vec2<S> &v) const |
|
{ |
|
return x != v.x || y != v.y; |
|
} |
|
|
|
template <class T> |
|
bool |
|
Vec2<T>::equalWithAbsError (const Vec2<T> &v, T e) const |
|
{ |
|
for (int i = 0; i < 2; i++) |
|
if (!Imath::equalWithAbsError ((*this)[i], v[i], e)) |
|
return false; |
|
|
|
return true; |
|
} |
|
|
|
template <class T> |
|
bool |
|
Vec2<T>::equalWithRelError (const Vec2<T> &v, T e) const |
|
{ |
|
for (int i = 0; i < 2; i++) |
|
if (!Imath::equalWithRelError ((*this)[i], v[i], e)) |
|
return false; |
|
|
|
return true; |
|
} |
|
|
|
template <class T> |
|
inline T |
|
Vec2<T>::dot (const Vec2 &v) const |
|
{ |
|
return x * v.x + y * v.y; |
|
} |
|
|
|
template <class T> |
|
inline T |
|
Vec2<T>::operator ^ (const Vec2 &v) const |
|
{ |
|
return dot (v); |
|
} |
|
|
|
template <class T> |
|
inline T |
|
Vec2<T>::cross (const Vec2 &v) const |
|
{ |
|
return x * v.y - y * v.x; |
|
|
|
} |
|
|
|
template <class T> |
|
inline T |
|
Vec2<T>::operator % (const Vec2 &v) const |
|
{ |
|
return x * v.y - y * v.x; |
|
} |
|
|
|
template <class T> |
|
inline const Vec2<T> & |
|
Vec2<T>::operator += (const Vec2 &v) |
|
{ |
|
x += v.x; |
|
y += v.y; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline Vec2<T> |
|
Vec2<T>::operator + (const Vec2 &v) const |
|
{ |
|
return Vec2 (x + v.x, y + v.y); |
|
} |
|
|
|
template <class T> |
|
inline const Vec2<T> & |
|
Vec2<T>::operator -= (const Vec2 &v) |
|
{ |
|
x -= v.x; |
|
y -= v.y; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline Vec2<T> |
|
Vec2<T>::operator - (const Vec2 &v) const |
|
{ |
|
return Vec2 (x - v.x, y - v.y); |
|
} |
|
|
|
template <class T> |
|
inline Vec2<T> |
|
Vec2<T>::operator - () const |
|
{ |
|
return Vec2 (-x, -y); |
|
} |
|
|
|
template <class T> |
|
inline const Vec2<T> & |
|
Vec2<T>::negate () |
|
{ |
|
x = -x; |
|
y = -y; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline const Vec2<T> & |
|
Vec2<T>::operator *= (const Vec2 &v) |
|
{ |
|
x *= v.x; |
|
y *= v.y; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline const Vec2<T> & |
|
Vec2<T>::operator *= (T a) |
|
{ |
|
x *= a; |
|
y *= a; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline Vec2<T> |
|
Vec2<T>::operator * (const Vec2 &v) const |
|
{ |
|
return Vec2 (x * v.x, y * v.y); |
|
} |
|
|
|
template <class T> |
|
inline Vec2<T> |
|
Vec2<T>::operator * (T a) const |
|
{ |
|
return Vec2 (x * a, y * a); |
|
} |
|
|
|
template <class T> |
|
inline const Vec2<T> & |
|
Vec2<T>::operator /= (const Vec2 &v) |
|
{ |
|
x /= v.x; |
|
y /= v.y; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline const Vec2<T> & |
|
Vec2<T>::operator /= (T a) |
|
{ |
|
x /= a; |
|
y /= a; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline Vec2<T> |
|
Vec2<T>::operator / (const Vec2 &v) const |
|
{ |
|
return Vec2 (x / v.x, y / v.y); |
|
} |
|
|
|
template <class T> |
|
inline Vec2<T> |
|
Vec2<T>::operator / (T a) const |
|
{ |
|
return Vec2 (x / a, y / a); |
|
} |
|
|
|
template <class T> |
|
inline T |
|
Vec2<T>::length () const |
|
{ |
|
return Math<T>::sqrt (dot (*this)); |
|
} |
|
|
|
template <class T> |
|
inline T |
|
Vec2<T>::length2 () const |
|
{ |
|
return dot (*this); |
|
} |
|
|
|
template <class T> |
|
const Vec2<T> & |
|
Vec2<T>::normalize () |
|
{ |
|
T l = length(); |
|
|
|
if (l != 0) |
|
{ |
|
x /= l; |
|
y /= l; |
|
} |
|
|
|
return *this; |
|
} |
|
|
|
template <class T> |
|
const Vec2<T> & |
|
Vec2<T>::normalizeExc () throw (Iex::MathExc) |
|
{ |
|
T l = length(); |
|
|
|
if (l == 0) |
|
throw NullVecExc ("Cannot normalize null vector."); |
|
|
|
x /= l; |
|
y /= l; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline |
|
const Vec2<T> & |
|
Vec2<T>::normalizeNonNull () |
|
{ |
|
T l = length(); |
|
x /= l; |
|
y /= l; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
Vec2<T> |
|
Vec2<T>::normalized () const |
|
{ |
|
T l = length(); |
|
|
|
if (l == 0) |
|
return Vec2 (T (0)); |
|
|
|
return Vec2 (x / l, y / l); |
|
} |
|
|
|
template <class T> |
|
Vec2<T> |
|
Vec2<T>::normalizedExc () const throw (Iex::MathExc) |
|
{ |
|
T l = length(); |
|
|
|
if (l == 0) |
|
throw NullVecExc ("Cannot normalize null vector."); |
|
|
|
return Vec2 (x / l, y / l); |
|
} |
|
|
|
template <class T> |
|
inline |
|
Vec2<T> |
|
Vec2<T>::normalizedNonNull () const |
|
{ |
|
T l = length(); |
|
return Vec2 (x / l, y / l); |
|
} |
|
|
|
|
|
//----------------------- |
|
// Implementation of Vec3 |
|
//----------------------- |
|
|
|
template <class T> |
|
inline T & |
|
Vec3<T>::operator [] (int i) |
|
{ |
|
return (&x)[i]; |
|
} |
|
|
|
template <class T> |
|
inline const T & |
|
Vec3<T>::operator [] (int i) const |
|
{ |
|
return (&x)[i]; |
|
} |
|
|
|
template <class T> |
|
inline |
|
Vec3<T>::Vec3 () |
|
{ |
|
// empty |
|
} |
|
|
|
template <class T> |
|
inline |
|
Vec3<T>::Vec3 (T a) |
|
{ |
|
x = y = z = a; |
|
} |
|
|
|
template <class T> |
|
inline |
|
Vec3<T>::Vec3 (T a, T b, T c) |
|
{ |
|
x = a; |
|
y = b; |
|
z = c; |
|
} |
|
|
|
template <class T> |
|
inline |
|
Vec3<T>::Vec3 (const Vec3 &v) |
|
{ |
|
x = v.x; |
|
y = v.y; |
|
z = v.z; |
|
} |
|
|
|
template <class T> |
|
template <class S> |
|
inline |
|
Vec3<T>::Vec3 (const Vec3<S> &v) |
|
{ |
|
x = T (v.x); |
|
y = T (v.y); |
|
z = T (v.z); |
|
} |
|
|
|
template <class T> |
|
inline const Vec3<T> & |
|
Vec3<T>::operator = (const Vec3 &v) |
|
{ |
|
x = v.x; |
|
y = v.y; |
|
z = v.z; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
template <class S> |
|
inline void |
|
Vec3<T>::setValue (S a, S b, S c) |
|
{ |
|
x = T (a); |
|
y = T (b); |
|
z = T (c); |
|
} |
|
|
|
template <class T> |
|
template <class S> |
|
inline void |
|
Vec3<T>::setValue (const Vec3<S> &v) |
|
{ |
|
x = T (v.x); |
|
y = T (v.y); |
|
z = T (v.z); |
|
} |
|
|
|
template <class T> |
|
template <class S> |
|
inline void |
|
Vec3<T>::getValue (S &a, S &b, S &c) const |
|
{ |
|
a = S (x); |
|
b = S (y); |
|
c = S (z); |
|
} |
|
|
|
template <class T> |
|
template <class S> |
|
inline void |
|
Vec3<T>::getValue (Vec3<S> &v) const |
|
{ |
|
v.x = S (x); |
|
v.y = S (y); |
|
v.z = S (z); |
|
} |
|
|
|
template <class T> |
|
inline T * |
|
Vec3<T>::getValue() |
|
{ |
|
return (T *) &x; |
|
} |
|
|
|
template <class T> |
|
inline const T * |
|
Vec3<T>::getValue() const |
|
{ |
|
return (const T *) &x; |
|
} |
|
|
|
template <class T> |
|
template <class S> |
|
inline bool |
|
Vec3<T>::operator == (const Vec3<S> &v) const |
|
{ |
|
return x == v.x && y == v.y && z == v.z; |
|
} |
|
|
|
template <class T> |
|
template <class S> |
|
inline bool |
|
Vec3<T>::operator != (const Vec3<S> &v) const |
|
{ |
|
return x != v.x || y != v.y || z != v.z; |
|
} |
|
|
|
template <class T> |
|
bool |
|
Vec3<T>::equalWithAbsError (const Vec3<T> &v, T e) const |
|
{ |
|
for (int i = 0; i < 3; i++) |
|
if (!Imath::equalWithAbsError ((*this)[i], v[i], e)) |
|
return false; |
|
|
|
return true; |
|
} |
|
|
|
template <class T> |
|
bool |
|
Vec3<T>::equalWithRelError (const Vec3<T> &v, T e) const |
|
{ |
|
for (int i = 0; i < 3; i++) |
|
if (!Imath::equalWithRelError ((*this)[i], v[i], e)) |
|
return false; |
|
|
|
return true; |
|
} |
|
|
|
template <class T> |
|
inline T |
|
Vec3<T>::dot (const Vec3 &v) const |
|
{ |
|
return x * v.x + y * v.y + z * v.z; |
|
} |
|
|
|
template <class T> |
|
inline T |
|
Vec3<T>::operator ^ (const Vec3 &v) const |
|
{ |
|
return dot (v); |
|
} |
|
|
|
template <class T> |
|
inline Vec3<T> |
|
Vec3<T>::cross (const Vec3 &v) const |
|
{ |
|
return Vec3 (y * v.z - z * v.y, |
|
z * v.x - x * v.z, |
|
x * v.y - y * v.x); |
|
} |
|
|
|
template <class T> |
|
inline const Vec3<T> & |
|
Vec3<T>::operator %= (const Vec3 &v) |
|
{ |
|
T a = y * v.z - z * v.y; |
|
T b = z * v.x - x * v.z; |
|
T c = x * v.y - y * v.x; |
|
x = a; |
|
y = b; |
|
z = c; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline Vec3<T> |
|
Vec3<T>::operator % (const Vec3 &v) const |
|
{ |
|
return Vec3 (y * v.z - z * v.y, |
|
z * v.x - x * v.z, |
|
x * v.y - y * v.x); |
|
} |
|
|
|
template <class T> |
|
inline const Vec3<T> & |
|
Vec3<T>::operator += (const Vec3 &v) |
|
{ |
|
x += v.x; |
|
y += v.y; |
|
z += v.z; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline Vec3<T> |
|
Vec3<T>::operator + (const Vec3 &v) const |
|
{ |
|
return Vec3 (x + v.x, y + v.y, z + v.z); |
|
} |
|
|
|
template <class T> |
|
inline const Vec3<T> & |
|
Vec3<T>::operator -= (const Vec3 &v) |
|
{ |
|
x -= v.x; |
|
y -= v.y; |
|
z -= v.z; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline Vec3<T> |
|
Vec3<T>::operator - (const Vec3 &v) const |
|
{ |
|
return Vec3 (x - v.x, y - v.y, z - v.z); |
|
} |
|
|
|
template <class T> |
|
inline Vec3<T> |
|
Vec3<T>::operator - () const |
|
{ |
|
return Vec3 (-x, -y, -z); |
|
} |
|
|
|
template <class T> |
|
inline const Vec3<T> & |
|
Vec3<T>::negate () |
|
{ |
|
x = -x; |
|
y = -y; |
|
z = -z; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline const Vec3<T> & |
|
Vec3<T>::operator *= (const Vec3 &v) |
|
{ |
|
x *= v.x; |
|
y *= v.y; |
|
z *= v.z; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline const Vec3<T> & |
|
Vec3<T>::operator *= (T a) |
|
{ |
|
x *= a; |
|
y *= a; |
|
z *= a; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline Vec3<T> |
|
Vec3<T>::operator * (const Vec3 &v) const |
|
{ |
|
return Vec3 (x * v.x, y * v.y, z * v.z); |
|
} |
|
|
|
template <class T> |
|
inline Vec3<T> |
|
Vec3<T>::operator * (T a) const |
|
{ |
|
return Vec3 (x * a, y * a, z * a); |
|
} |
|
|
|
template <class T> |
|
inline const Vec3<T> & |
|
Vec3<T>::operator /= (const Vec3 &v) |
|
{ |
|
x /= v.x; |
|
y /= v.y; |
|
z /= v.z; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline const Vec3<T> & |
|
Vec3<T>::operator /= (T a) |
|
{ |
|
x /= a; |
|
y /= a; |
|
z /= a; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline Vec3<T> |
|
Vec3<T>::operator / (const Vec3 &v) const |
|
{ |
|
return Vec3 (x / v.x, y / v.y, z / v.z); |
|
} |
|
|
|
template <class T> |
|
inline Vec3<T> |
|
Vec3<T>::operator / (T a) const |
|
{ |
|
return Vec3 (x / a, y / a, z / a); |
|
} |
|
|
|
|
|
template <class T> |
|
inline T |
|
Vec3<T>::length () const |
|
{ |
|
return Math<T>::sqrt (dot (*this)); |
|
} |
|
|
|
template <class T> |
|
inline T |
|
Vec3<T>::length2 () const |
|
{ |
|
return dot (*this); |
|
} |
|
|
|
template <class T> |
|
const Vec3<T> & |
|
Vec3<T>::normalize () |
|
{ |
|
T l = length(); |
|
|
|
if (l != 0) |
|
{ |
|
x /= l; |
|
y /= l; |
|
z /= l; |
|
} |
|
|
|
return *this; |
|
} |
|
|
|
template <class T> |
|
const Vec3<T> & |
|
Vec3<T>::normalizeExc () throw (Iex::MathExc) |
|
{ |
|
T l = length(); |
|
|
|
if (l == 0) |
|
throw NullVecExc ("Cannot normalize null vector."); |
|
|
|
x /= l; |
|
y /= l; |
|
z /= l; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
inline |
|
const Vec3<T> & |
|
Vec3<T>::normalizeNonNull () |
|
{ |
|
T l = length(); |
|
x /= l; |
|
y /= l; |
|
z /= l; |
|
return *this; |
|
} |
|
|
|
template <class T> |
|
Vec3<T> |
|
Vec3<T>::normalized () const |
|
{ |
|
T l = length(); |
|
|
|
if (l == 0) |
|
return Vec3 (T (0)); |
|
|
|
return Vec3 (x / l, y / l, z / l); |
|
} |
|
|
|
template <class T> |
|
Vec3<T> |
|
Vec3<T>::normalizedExc () const throw (Iex::MathExc) |
|
{ |
|
T l = length(); |
|
|
|
if (l == 0) |
|
throw NullVecExc ("Cannot normalize null vector."); |
|
|
|
return Vec3 (x / l, y / l, z / l); |
|
} |
|
|
|
template <class T> |
|
inline |
|
Vec3<T> |
|
Vec3<T>::normalizedNonNull () const |
|
{ |
|
T l = length(); |
|
return Vec3 (x / l, y / l, z / l); |
|
} |
|
|
|
|
|
//----------------------------- |
|
// Stream output implementation |
|
//----------------------------- |
|
|
|
template <class T> |
|
std::ostream & |
|
operator << (std::ostream &s, const Vec2<T> &v) |
|
{ |
|
return s << '(' << v.x << ' ' << v.y << ')'; |
|
} |
|
|
|
template <class T> |
|
std::ostream & |
|
operator << (std::ostream &s, const Vec3<T> &v) |
|
{ |
|
return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')'; |
|
} |
|
|
|
|
|
//----------------------------------------- |
|
// Implementation of reverse multiplication |
|
//----------------------------------------- |
|
|
|
template <class T> |
|
inline Vec2<T> |
|
operator * (T a, const Vec2<T> &v) |
|
{ |
|
return Vec2<T> (a * v.x, a * v.y); |
|
} |
|
|
|
template <class T> |
|
inline Vec3<T> |
|
operator * (T a, const Vec3<T> &v) |
|
{ |
|
return Vec3<T> (a * v.x, a * v.y, a * v.z); |
|
} |
|
|
|
|
|
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER |
|
#pragma warning(default:4290) |
|
#endif |
|
|
|
} // namespace Imath |
|
|
|
#endif
|
|
|