//see main.cc for copyright notices
#ifndef VECTOR_H
#define VECTOR_H 1
#include <math.h>
class ostream;
class istream;
class Vector {
double d[3];
public:
inline Vector (double x, double y, double z=0);
inline Vector(const Vector& v);
inline Vector();
inline double length() const;
inline double length2() const;
inline Vector& operator=(const Vector& v);
inline bool operator==(const Vector& v) const;
inline Vector operator*(double s) const;
inline Vector operator*(const Vector& v) const;
inline Vector operator/(const Vector& v) const;
inline Vector& operator*=(double s);
Vector operator/(double s) const;
inline Vector operator+(const Vector& v) const;
inline Vector& operator+=(const Vector& v);
inline Vector operator-() const;
inline Vector operator-(const Vector& v) const;
Vector& operator-=(const Vector& v);
inline double normalize();
Vector normal() const;
inline Vector cross(const Vector& v) const;
inline double dot(const Vector& v) const;
inline void x(double xx) { d[0]=xx; }
inline double x() const;
inline void y(double yy) { d[1]=yy; }
inline double y() const;
inline void z(double zz) { d[2]=zz; }
inline double z() const;
inline double minComponent() const;
friend ostream& operator<<(ostream& os, const Vector& p);
friend istream& operator>>(istream& os, Vector& p);
inline bool operator != (const Vector& v) const;
inline double* ptr() const {return (double*)&d[0];}
void make_ortho(Vector&v1, Vector&v2)
{
Vector v0(this->cross(Vector(1,0,0)));
if(v0.length2() == 0){
v0=this->cross(this->cross(Vector(0,1,0)));
}
v1=this->cross(v0);
v1.normalize();
v2=this->cross(v1);
v2.normalize();
}
};
inline Vector::Vector(double x, double y, double z) {
d[0]=x;
d[1]=y;
d[2]=z;
}
inline Vector::Vector(const Vector& v) {
d[0]=v.d[0];
d[1]=v.d[1];
d[2]=v.d[2];
}
inline Vector::Vector() {
}
inline double Vector::length() const {
return sqrt(length2());
}
inline double Vector::length2() const {
return d[0]*d[0]+d[1]*d[1]+d[2]*d[2];
}
inline Vector& Vector::operator=(const Vector& v) {
d[0]=v.d[0];
d[1]=v.d[1];
d[2]=v.d[2];
return *this;
}
inline Vector Vector::operator*(double s) const {
return Vector(d[0]*s, d[1]*s, d[2]*s);
}
inline Vector operator*(double s, const Vector& v) {
return v*s;
}
inline Vector Vector::operator*(const Vector& v) const {
return Vector(d[0]*v.d[0], d[1]*v.d[1], d[2]*v.d[2]);
}
inline Vector Vector::operator/(const Vector& v) const {
return Vector(d[0]/v.d[0], d[1]/v.d[1], d[2]/v.d[2]);
}
inline Vector Vector::operator+(const Vector& v) const {
return Vector(d[0]+v.d[0], d[1]+v.d[1], d[2]+v.d[2]);
}
inline Vector& Vector::operator+=(const Vector& v) {
d[0]+=v.d[0];
d[1]+=v.d[1];
d[2]+=v.d[2];
return *this;
}
inline Vector& Vector::operator*=(double s) {
d[0]*=s;
d[1]*=s;
d[2]*=s;
return *this;
}
inline Vector Vector::operator-() const {
return Vector(-d[0], -d[1], -d[2]);
}
inline Vector Vector::operator-(const Vector& v) const {
return Vector(d[0]-v.d[0], d[1]-v.d[1], d[2]-v.d[2]);
}
inline double Vector::normalize() {
double l=length();
if(l != 0)
{
d[0]/=l;
d[1]/=l;
d[2]/=l;
}
return l;
}
inline Vector Vector::cross(const Vector& v) const {
return Vector(d[1]*v.d[2]-d[2]*v.d[1],
d[2]*v.d[0]-d[0]*v.d[2],
d[0]*v.d[1]-d[1]*v.d[0]);
}
inline double Vector::dot(const Vector& v) const {
return d[0]*v.d[0]+d[1]*v.d[1]+d[2]*v.d[2];
}
inline double Vector::x() const {
return d[0];
}
inline double Vector::y() const {
return d[1];
}
inline double Vector::z() const {
return d[2];
}
inline double Vector::minComponent() const {
return (d[0]<d[1] && d[0]<d[2])?d[0]:d[1]<d[2]?d[1]:d[2];
}
inline bool Vector::operator != (const Vector& v) const {
return d[0] != v.d[0] || d[1] != v.d[1] || d[2] != v.d[2];
}
inline bool Vector::operator == (const Vector& v) const {
return d[0] == v.d[0] && d[1] == v.d[1] && d[2] == v.d[2];
}
#endif