/***************************************************************************************
*****	                  CLASS VECTOR IMPLEMENTATION                              *****
****************************************************************************************
** Author: Peter Stuart
** Email:  chester@selway.umt.edu
** Date:   3/7/98
** Description: This class implements a four dimensional vector. Operations include
**   scalar product (dot product), vector product (cross product), magnitude, direction,
**   projection on another vector, angle between two vectors, and vector arithmetic.
**
** NOTE: The matrices, vectors, and points use homogeneous coordinates
** 	
***************************************************************************************/

#include "Vector.hpp"

/* Constructors ***********
** Default values for private variables:
** _x = 0.0
** _y = 0.0
** _z = 0.0
** _w = 1.0
*/

Vector::Vector(const double xin, const double yin, const double zin, const double win) 
{
   _x = xin;
   _y = yin;
   _z = zin;
   _w = win;
}

Vector::Vector(const double p1x, const double p1y, const double p1z, 
               const double p2x, const double p2y, const double p2z, 
               const double pw) 
{
   _x = p2x - p1x;
   _y = p2y - p1y;
   _z = p2z - p1z;
   _w = pw;
}

// Copy Constructor
Vector::Vector(const Vector& vec)
{
   _x = vec._x;
   _y = vec._y;
   _z = vec._z;
   _w = vec._w;
}

// Destructor
Vector::~Vector()
{
   ;
}

// BASIC VECTOR OPERATIONS /////////////////////////////////////

// Vector Cross product
Vector  Vector::cross(const Vector& vec) const
{
   Vector temp;   // returning vector

   temp._x = _y*vec._z - _z*vec._y;
   temp._y = _z*vec._x - _x*vec._z;
   temp._z = _x*vec._y - _y*vec._x;

   return temp;
}

// Vector Dot product
double  Vector::dot(const Vector& vec) const
{
   return (_x*vec._x + _y*vec._y + _z*vec._z);
}

// Magnitude or length of vector
double  Vector::magnitude() const
{
   return (double)sqrt(_x*_x + _y*_y + _z*_z);
}

// Direction of vector or unit vector
Vector  Vector::direction() 
{
   double mag = magnitude();

   // avoid divide by zero by cheating
   if (mag == 0.0) {
      mag = 0.00000001;
   }

   Vector temp(_x/mag, _y/mag, _z/mag);   // returning vector
   return temp;
}

// Projection of vector on another vector
Vector  Vector::projection(const Vector& vec)
{
   Vector temp(_x, _y, _z);
   return (temp.dot(vec)/temp.dot(temp))*temp;
}

// angle between two vectors in radians
double  Vector::angle(const Vector& vec) 
{
   Vector temp(_x, _y, _z);   
   return acos(temp.dot(vec)/(temp.magnitude()*vec.magnitude()));
}

// ELEMENTARY OPERATORS //////////////////////

// Assignment operator
Vector&  Vector::operator = (const Vector& vec)
{
   if (this == &vec)
      return *this;

   _x = vec._x;
   _y = vec._y;
   _z = vec._z;
   _w = vec._w;

   return (*this);
}

// Scalar multiple
Vector  operator * (const Vector& vec, const double val)
{
   Vector temp;   // returning vector

   temp._x = vec._x*val;
   temp._y = vec._y*val;
   temp._z = vec._z*val;

   return temp;
}

Vector  operator * (const double val, const Vector& vec)
{
   Vector temp;   // returning vector

   temp._x = vec._x*val;
   temp._y = vec._y*val;
   temp._z = vec._z*val;

   return temp;
}

// Vector product (Cross product)
Vector  operator * (const Vector& vec1, const Vector& vec2)
{
   Vector temp;   // returning vector

   temp._x = vec1._y*vec2._z - vec1._z*vec2._y;
   temp._y = vec1._z*vec2._x - vec1._x*vec2._z;
   temp._z = vec1._x*vec2._y - vec1._y*vec2._x;

   return temp;
}

// scalar divide
Vector operator / (const Vector& vec, const double val)
{
   Vector temp;   // returning vector

   temp._x = vec._x/val;
   temp._y = vec._y/val;
   temp._z = vec._z/val;

   return temp;
}

// Vector addition
Vector  operator + (const Vector& vec1, const Vector& vec2)
{
   Vector temp;   // returning vector

   temp._x = vec1._x + vec2._x;
   temp._y = vec1._y + vec2._y;
   temp._z = vec1._z + vec2._z;

   return temp;
}

// Vector subtraction
Vector  operator - (const Vector& vec1, const Vector& vec2)
{
   Vector temp;   // returning vector

   temp._x = vec1._x - vec2._x;
   temp._y = vec1._y - vec2._y;
   temp._z = vec1._z - vec2._z;

   return temp;
}

// negative vector
Vector  operator - (const Vector& vec)
{
   Vector temp;   // returning vector

   temp._x = -vec._x;
   temp._y = -vec._y;
   temp._z = -vec._z;

   return temp;
}

// assignment of addition of vector to itself
Vector& Vector::operator += (const Vector& vec)
{
   _x += vec._x;
   _y += vec._y;
   _z += vec._z;
   return *this;
}

// assignment of subtraction of vector to itself
Vector& Vector::operator -= (const Vector& vec)
{
   _x -= vec._x;
   _y -= vec._y;
   _z -= vec._z;
   return *this;
}

// assignment of multiplication of scalar to vector
Vector& Vector::operator *= (const double val)
{
   _x *= val;
   _y *= val;
   _z *= val;
   return *this;
}

// assignment of division by scalr to vector
Vector& Vector::operator /= (const double val)
{
   _x /= val;
   _y /= val;
   _z /= val;
   return *this;
}

// Relational operators
int  operator == (const Vector& vec1, const Vector& vec2) 
{
   if (vec1._x != vec2._x)
      return FALSE;
   if (vec1._y != vec2._y)
      return FALSE;
   if (vec1._z != vec2._z)
      return FALSE;

   return TRUE;
}

int  operator != (const Vector& vec1, const Vector& vec2)
{
   if (vec1._x == vec2._x)
      return FALSE;
   if (vec1._y == vec2._y)
      return FALSE;
   if (vec1._z == vec2._z)
      return FALSE;

   return TRUE;
}

// output stream
ostream& operator << (ostream& co, const Vector& vec)
{
   co << "<" << vec._x << ", "
             << vec._y << ", "
             << vec._z << ", "
             << vec._w << ">";

   return co;
}

    Source: geocities.com/collegepark/4206

               ( geocities.com/collegepark)