////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2008 The Regents of the University of California
//
// This file is part of Qbox
//
// Qbox is distributed under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 2 of
// the License, or (at your option) any later version.
// See the file COPYING in the root directory of this distribution
// or .
//
////////////////////////////////////////////////////////////////////////////////
//
// D3vector.h
//
// double 3-vectors
//
////////////////////////////////////////////////////////////////////////////////
#ifndef D3VECTOR_H
#define D3VECTOR_H
#include
#include
#include
class D3vector
{
public:
double x, y, z;
// explicit constructor to avoid implicit conversion from double to D3vector
explicit D3vector(const double& xv, const double& yv, const double& zv) :
x(xv), y(yv), z(zv) {}
explicit D3vector(void) : x(0.0), y(0.0), z(0.0) {}
explicit D3vector(const double* r) : x(r[0]), y(r[1]), z(r[2]) {}
double& operator[](const int &i)
{
assert(i>=0 && i <3);
if ( i == 0 ) return x;
else if ( i == 1 ) return y;
else return z;
}
double operator[] (const int &i) const
{
assert(i>=0 && i <3);
if ( i == 0 ) return x;
else if ( i == 1 ) return y;
else return z;
}
bool operator==(const D3vector &rhs) const
{
return x == rhs.x && y == rhs.y && z == rhs.z;
}
bool operator!=(const D3vector &rhs) const
{
return x != rhs.x || y != rhs.y || z != rhs.z;
}
D3vector& operator += ( const D3vector& rhs )
{
x += rhs.x; y += rhs.y; z += rhs.z;
return *this;
}
D3vector& operator -= ( const D3vector& rhs )
{
x -= rhs.x; y -= rhs.y; z -= rhs.z;
return *this;
}
D3vector& operator *= ( const double& rhs )
{
x *= rhs; y *= rhs; z *= rhs;
return *this;
}
D3vector& operator /= ( const double& rhs )
{
x /= rhs; y /= rhs; z /= rhs;
return *this;
}
friend const D3vector operator + (const D3vector& lhs, const D3vector& rhs )
{
return D3vector(lhs) += rhs;
}
friend const D3vector operator - ( const D3vector& a, const D3vector& b )
{
return D3vector(a) -= b;
}
friend D3vector operator - ( const D3vector& a ) // unary minus
{
return D3vector( -a.x, -a.y, -a.z );
}
friend D3vector operator * ( const double& a, const D3vector& b )
{
return D3vector(b) *= a;
}
friend D3vector operator * ( const D3vector& a, const double& b )
{
return D3vector(a) *= b;
}
friend D3vector operator / ( const D3vector& a, const double& b )
{
return D3vector(a) /= b;
}
// scalar product
friend double operator * ( const D3vector& a, const D3vector& b )
{
return a.x * b.x + a.y * b.y + a.z * b.z ;
}
friend D3vector operator ^ ( const D3vector& a, const D3vector& b )
{
return D3vector( a.y * b.z - a.z * b.y ,
a.z * b.x - a.x * b.z ,
a.x * b.y - a.y * b.x );
}
friend D3vector rotate ( const D3vector& x, const D3vector& w )
{
if ( length(x) == 0.0 ) return x; // x has zero length
double theta = length( w ); // rotate by zero
if ( theta == 0.0 ) return x;
D3vector ew = normalized ( w );
D3vector v = w ^ x;
if ( length( v ) == 0.0 ) return x; // x is parallel to the rotation axis
v = normalized( v );
D3vector u = v ^ ew;
double p = x * u;
return (x*ew)*ew + p*cos(theta)*u + p*sin(theta)*v ;
}
friend double length( const D3vector& a )
{
return sqrt( a.x * a.x + a.y * a.y + a.z * a.z );
}
friend double norm2( const D3vector& a )
{
return a.x * a.x + a.y * a.y + a.z * a.z;
}
friend D3vector normalized( const D3vector a )
{
return a / length( a );
}
friend std::ostream& operator << ( std::ostream& os, const D3vector& v )
{
os << v.x << " " << v.y << " " << v.z;
return os;
}
friend std::istream& operator >> ( std::istream& is, D3vector& v )
{
is >> v.x >> v.y >> v.z ;
return is;
}
};
#endif