433 lines
7.8 KiB
C++
433 lines
7.8 KiB
C++
//------------------------------------------------------------------------------
|
|
// Author: Gero Mueller <gero.mueller@cloo.de>
|
|
// Copyright: (c) 2006 Gero Mueller
|
|
// License: MIT License
|
|
//------------------------------------------------------------------------------
|
|
|
|
#ifndef BLUECORE_VECTOR_H
|
|
#define BLUECORE_VECTOR_H
|
|
|
|
// system includes
|
|
#include <cmath>
|
|
#include <ostream>
|
|
|
|
// project includes
|
|
#include "Scalar.h"
|
|
|
|
namespace BlueCore
|
|
{
|
|
template <class T>
|
|
class Vector3Template
|
|
{
|
|
public:
|
|
|
|
T x, y, z;
|
|
|
|
/**
|
|
* Default Contructor
|
|
*/
|
|
inline Vector3Template()
|
|
{
|
|
x = static_cast<T>(0);
|
|
y = static_cast<T>(0);
|
|
z = static_cast<T>(0);
|
|
}
|
|
|
|
/**
|
|
* Constructor from three values
|
|
*/
|
|
template <class S>
|
|
inline Vector3Template( S x, S y, S z )
|
|
{
|
|
this->x = static_cast<T>(x);
|
|
this->y = static_cast<T>(y);
|
|
this->z = static_cast<T>(z);
|
|
}
|
|
|
|
/**
|
|
* copy contructor
|
|
*/
|
|
template <class S>
|
|
inline Vector3Template( Vector3Template<S> &a )
|
|
{
|
|
x = static_cast<T>(a.x);
|
|
y = static_cast<T>(a.y);
|
|
z = static_cast<T>(a.z);
|
|
}
|
|
|
|
|
|
/**
|
|
* add operataor
|
|
*/
|
|
template <class S>
|
|
inline Vector3Template<T> operator + (
|
|
const Vector3Template<S> &a ) const
|
|
{
|
|
return Vector3Template<T>(
|
|
x + static_cast<T>(a.x),
|
|
y + static_cast<T>(a.y),
|
|
z + static_cast<T>(a.z) );
|
|
}
|
|
|
|
|
|
/**
|
|
* zero the vector
|
|
*/
|
|
inline void zero()
|
|
{
|
|
x = static_cast<T>(0);
|
|
y = static_cast<T>(0);
|
|
z = static_cast<T>(0);
|
|
}
|
|
|
|
/**
|
|
* zero the vector
|
|
*/
|
|
inline bool isZero() const
|
|
{
|
|
if( x != 0.0 )
|
|
return false;
|
|
|
|
if( y != 0.0 )
|
|
return false;
|
|
|
|
if( z != 0.0 )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* add-assign operator
|
|
*/
|
|
template <class S>
|
|
inline Vector3Template<T> &operator += (
|
|
const Vector3Template<S> &a )
|
|
{
|
|
x += static_cast<T>(a.x);
|
|
y += static_cast<T>(a.y);
|
|
z += static_cast<T>(a.z);
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
/**
|
|
* sub operator
|
|
*/
|
|
template <class S>
|
|
inline Vector3Template<T> operator - (
|
|
const Vector3Template<S> &a ) const
|
|
{
|
|
return Vector3Template<T>(
|
|
x - static_cast<T>(a.x),
|
|
y - static_cast<T>(a.y),
|
|
z - static_cast<T>(a.z)
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
* sub-assign operator
|
|
*/
|
|
template <class S>
|
|
inline Vector3Template<T> &operator -= (
|
|
const Vector3Template<S> &a )
|
|
{
|
|
x -= static_cast<T>(a.x);
|
|
y -= static_cast<T>(a.y);
|
|
z -= static_cast<T>(a.z);
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
/**
|
|
* multiply by scalar operator
|
|
*/
|
|
template <class S>
|
|
inline Vector3Template<T> operator * ( const S a ) const
|
|
{
|
|
return Vector3Template<T>(
|
|
x * static_cast<T>(a),
|
|
y * static_cast<T>(a),
|
|
z * static_cast<T>(a)
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
* multiply-assign by scalar operator
|
|
*/
|
|
template <class S>
|
|
inline Vector3Template<T> &operator *= ( const S a )
|
|
{
|
|
x *= static_cast<T>(a);
|
|
y *= static_cast<T>(a);
|
|
z *= static_cast<T>(a);
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
/**
|
|
* divide by scalar operator
|
|
*/
|
|
template <class S>
|
|
inline Vector3Template<T> operator / ( const S a ) const
|
|
{
|
|
return Vector3Template<T>(
|
|
x / static_cast<T>(a),
|
|
y / static_cast<T>(a),
|
|
z / static_cast<T>(a)
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
* divide-assign by scalar operator
|
|
*/
|
|
template <class S>
|
|
inline Vector3Template<T> &operator /= ( const S a )
|
|
{
|
|
x /= static_cast<T>(a);
|
|
y /= static_cast<T>(a);
|
|
z /= static_cast<T>(a);
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
/**
|
|
* assign operator
|
|
*/
|
|
template <class S>
|
|
inline Vector3Template<T> operator = (
|
|
const Vector3Template<S> &a )
|
|
{
|
|
x = static_cast<T>(a.x);
|
|
y = static_cast<T>(a.y);
|
|
z = static_cast<T>(a.z);
|
|
|
|
return *this;
|
|
}
|
|
|
|
inline Vector3Template<T> operator - (void) const
|
|
{
|
|
return Vector3Template<T>( -x, -y, -z );
|
|
}
|
|
|
|
/**
|
|
* compare operator
|
|
*/
|
|
template <class S>
|
|
inline bool operator == ( const Vector3Template<S> &a )
|
|
{
|
|
if( x != static_cast<T>(a.x) )
|
|
return false;
|
|
|
|
if( y != static_cast<T>(a.y) )
|
|
return false;
|
|
|
|
if( z != static_cast<T>(a.z) )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* anti compare operator
|
|
*/
|
|
template <class S>
|
|
inline bool operator != ( const Vector3Template<S> &a )
|
|
{
|
|
if( x != static_cast<T>(a.x) )
|
|
return true;
|
|
|
|
if( y != static_cast<T>(a.y) )
|
|
return true;
|
|
|
|
if( z != static_cast<T>(a.z) )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* return the length of the vector
|
|
*/
|
|
inline T length() const
|
|
{
|
|
return static_cast<T>( sqrt(x*x + y*y + z*z) );
|
|
}
|
|
|
|
|
|
/**
|
|
* length squared
|
|
*/
|
|
inline T length2() const
|
|
{
|
|
return x*x + y*y + z*z;
|
|
}
|
|
|
|
|
|
/**
|
|
* calculate the cross product
|
|
*/
|
|
template <class S>
|
|
inline Vector3Template<T> cross(
|
|
const Vector3Template<S> &a ) const
|
|
{
|
|
return Vector3Template<T>(
|
|
y * static_cast<T>(a.z) - z * static_cast<T>(a.y),
|
|
z * static_cast<T>(a.x) - x * static_cast<T>(a.z),
|
|
x * static_cast<T>(a.y) - y * static_cast<T>(a.x)
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
* calculate dot product
|
|
*/
|
|
template <class S>
|
|
inline T dot( const Vector3Template<S> &a ) const
|
|
{
|
|
return (
|
|
x * static_cast<T>(a.x) +
|
|
y * static_cast<T>(a.y) +
|
|
z * static_cast<T>(a.z) );
|
|
}
|
|
|
|
|
|
/**
|
|
* check if vectors are nearly equal
|
|
*/
|
|
template <class S>
|
|
inline bool nearlyEquals(
|
|
const Vector3Template<S> &a,
|
|
T epsilon = 0.00001 ) const
|
|
{
|
|
if( fabs(x-static_cast<T>(a.x)) > epsilon )
|
|
return false;
|
|
|
|
if( fabs(y-static_cast<T>(a.y)) > epsilon )
|
|
return false;
|
|
|
|
if( fabs(z-static_cast<T>(a.z)) > epsilon )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* normalize the vector to length 1
|
|
*/
|
|
inline void normalize()
|
|
{
|
|
T a = length();
|
|
if( a == 0 )
|
|
return;
|
|
|
|
x /= a;
|
|
y /= a;
|
|
z /= a;
|
|
}
|
|
|
|
|
|
/**
|
|
* get normalized vector
|
|
*/
|
|
inline Vector3Template<T> normalized() const
|
|
{
|
|
T a = length();
|
|
if( a == 0 )
|
|
return Vector3Template<T>( 0.0, 0.0, 1.0 );
|
|
return Vector3Template<T>( x / a, y / a, z / a );
|
|
}
|
|
|
|
/**
|
|
* check if vectors are parallel
|
|
*/
|
|
inline bool parallel( const Vector3Template<T> &a ) const
|
|
{
|
|
return ( (static_cast<T>(a.x) / x) ==
|
|
(static_cast<T>(a.y) / y) ==
|
|
(static_cast<T>(a.z) / z) );
|
|
}
|
|
|
|
|
|
/**
|
|
* check if vectors are parallel
|
|
*/
|
|
template <class S>
|
|
inline bool nearlyParallel(
|
|
const Vector3Template<S> &a,
|
|
T epsilon = 0.00001 ) const
|
|
{
|
|
T ax = static_cast<T>(a.x) / x;
|
|
T ay = static_cast<T>(a.y) / y;
|
|
T az = static_cast<T>(a.z) / z;
|
|
|
|
if( fabs(ax - ay) > epsilon )
|
|
return false;
|
|
|
|
if( fabs(ax - az) > epsilon )
|
|
return false;
|
|
|
|
if( fabs(ay - az) > epsilon )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* check if vectors are orthogonal
|
|
*/
|
|
inline bool orthogonal( const Vector3Template<T> &a ) const
|
|
{
|
|
return ( dot(a) == static_cast<T>(0) );
|
|
}
|
|
|
|
|
|
/**
|
|
* check if vectors are orthogonal
|
|
*/
|
|
template <class S>
|
|
inline bool nearlyOrthogonal(
|
|
const Vector3Template<S> &a,
|
|
T epsilon = 0.00001 ) const
|
|
{
|
|
return ( dot(a) < epsilon );
|
|
}
|
|
|
|
T& operator[] (unsigned int i)
|
|
{
|
|
if( i == 0 )
|
|
return x;
|
|
else if( i == 1 )
|
|
return y;
|
|
else if( i == 2 )
|
|
return z;
|
|
else
|
|
throw "index out of bound";
|
|
}
|
|
|
|
friend std::ostream &operator << ( std::ostream& os, Vector3Template<T> v )
|
|
{
|
|
os << "( " << v.x << ", " << v.y << ", " << v.z << " )";
|
|
return os;
|
|
}
|
|
|
|
};
|
|
|
|
typedef Vector3Template<float> Vector3Float;
|
|
typedef Vector3Template<double> Vector3Double;
|
|
typedef Vector3Template<Scalar> Vector3;
|
|
}
|
|
|
|
#endif
|