Code:
#ifndef VECTOR_C
#define VECTOR_C
namespace psi
{
/* 'vector' is a 3D point object */
struct vector
{
vector(double x0 = 0, double y0 = 0, double z0 = 0);
inline
vector &
set(double x0, double y0, double z0);
inline
vector &
operator () (double x0, double y0, double z0);
inline
vector &
operator = (const vector & other);
inline
vector &
add(const vector & other);
inline
vector &
operator += (const vector & other);
inline
vector &
subtract(const vector & other);
inline
vector &
operator -= (const vector & other);
inline
vector &
multiply(const vector & other);
inline
vector &
operator *= (const vector & other);
inline
vector &
divide(const vector & other);
inline
vector &
operator /= (const vector & other);
inline
const vector
plus(const vector & other) const;
inline
const vector
operator + (const vector & other) const;
inline
const vector
minus(const vector & other) const;
inline
const vector
operator - (const vector & other) const;
inline
const vector
times(const vector & other) const;
inline
const vector
operator * (const vector & other) const;
inline
const vector
quotient(const vector & other) const;
inline
const vector
operator / (const vector & other) const;
inline
double
product(const vector & other) const;
inline
double
angle(const vector & other) const;
inline
double
product() const;
inline
double
length() const;
inline
vector &
normalize();
friend
ostream &
operator << (ostream & stream, vector & value)
{
return stream << "x( " << value.x << " ) y( " << value.y << " ) z( " << value.z << " )";
}
friend
istream &
operator >> (istream & stream, vector & value)
{
while(!(stream >> value.x))
{
stream.clear();
stream.ignore();
}
while(!(stream >> value.y))
{
stream.clear();
stream.ignore();
}
while(!(stream >> value.z))
{
stream.clear();
stream.ignore();
}
if(stream.peek() == '\n')
stream.get();
return stream;
}
public:
double x, y, z;
};
/* C-style inline functions */
inline
vector &
add(vector & dest, const vector & a, const vector & b)
{
dest.x = a.x + b.x;
dest.y = a.y + b.y;
dest.z = a.z + b.z;
return dest;
}
inline
vector &
add(vector & dest, const vector & src)
{
return add(dest, dest, src);
}
inline
vector &
subtract(vector & dest, const vector & a, const vector & b)
{
dest.x = a.x - b.x;
dest.y = a.y - b.y;
dest.z = a.z - b.z;
return dest;
}
inline
vector &
subtract(vector & dest, const vector & src)
{
return subtract(dest, dest, src);
}
inline
vector &
multiply(vector & dest, const vector & a, const vector & b)
{
dest.x = a.x * b.x;
dest.y = a.y * b.y;
dest.z = a.z * b.z;
return dest;
}
inline
vector &
multiply(vector & dest, const vector & src)
{
return multiply(dest, dest, src);
}
inline
vector &
divide(vector & dest, const vector & a, const vector & b)
{
dest.x = b.x == 0 ? 0 : a.x / b.x;
dest.y = b.y == 0 ? 0 : a.y / b.y;
dest.z = b.z == 0 ? 0 : a.z / b.z;
return dest;
}
inline
vector &
divide(vector & dest, const vector & src)
{
return divide(dest, dest, src);
}
inline
const vector
plus(const vector & a, const vector & b)
{
vector temp(a);
return vector(temp.add(b));
}
inline
const vector
minus(const vector & a, const vector & b)
{
vector temp(a);
return vector(temp.subtract(b));
}
inline
const vector
times(const vector & a, const vector & b)
{
vector temp(a);
return vector(temp.multiply(b));
}
inline
const vector
quotient(const vector & a, const vector & b)
{
vector temp(a);
return vector(temp.divide(b));
}
inline
double
product(const vector & a, const vector & b)
{
return (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
}
inline
double
product(const vector & a)
{
return product(a, a);
}
inline
double
length(const vector & a)
{
return sqrt(product(a));
}
inline
vector &
normalize(vector & a)
{
double length = a.length();
vector temp(length, length, length);
return a.divide(temp);
}
/* ??Yarghh! */
inline
double
angle(const vector & a, const vector & b)
{
double al = a.length(), bl = b.length();
return al && bl ? acos(product(a, b)/(al * bl)) : 0;
}
/* The implementation uses the inline C-style functions */
vector::
vector(double x0, double y0, double z0)
{
set(x0, y0, z0);
}
vector &
vector::
set(double x0, double y0, double z0)
{
x = x0, y = y0, z = z0;
return *this;
}
vector &
vector::
operator () (double x0, double y0, double z0)
{
return set(x0, y0, z0);
}
vector &
vector::
operator = (const vector & other)
{
return set(other.x, other.y, other.z);
}
vector &
vector::
add(const vector & other)
{
return psi::add(*this, other);
}
vector &
vector::
operator += (const vector & other)
{
return psi::add(*this, other);
}
vector &
vector::
subtract(const vector & other)
{
return psi::subtract(*this, other);
}
vector &
vector::
operator -= (const vector & other)
{
return psi::subtract(*this, other);
}
vector &
vector::
multiply(const vector & other)
{
return psi::multiply(*this, other);
}
vector &
vector::
operator *= (const vector & other)
{
return psi::multiply(*this, other);
}
vector &
vector::
divide(const vector & other)
{
return psi::divide(*this, other);
}
vector &
vector::
operator /= (const vector & other)
{
return psi::divide(*this, other);
}
const vector
vector::
plus(const vector & other) const
{
return psi::plus(*this, other);
}
const vector
vector::
operator + (const vector & other) const
{
return psi::plus(*this, other);
}
const vector
vector::
minus(const vector & other) const
{
return psi::minus(*this, other);
}
const vector
vector::
operator - (const vector & other) const
{
return psi::minus(*this, other);
}
const vector
vector::
times(const vector & other) const
{
return psi::times(*this, other);
}
const vector
vector::
operator * (const vector & other) const
{
return psi::times(*this, other);
}
const vector
vector::
quotient(const vector & other) const
{
return psi::quotient(*this, other);
}
const vector
vector::
operator / (const vector & other) const
{
return psi::quotient(*this, other);
}
double
vector::
product(const vector & other) const
{
return psi::product(*this, other);
}
double
vector::
product() const
{
return psi::product(*this);
}
double
vector::
length() const
{
return psi::length(*this);
}
vector &
vector::
normalize()
{
return psi::normalize(*this);
}
double
vector::
angle(const vector & other) const
{
return psi::angle(*this, other);
}
} // namespace
#endif // VECTOR_C