#ifndef _VECTORS_H_
#define _VECTORS_H_
//
// originally implemented by Justin Legakis
//
#include
using namespace std;
#include
#include
#include
#include
class Matrix;
// ====================================================================
// ====================================================================
class Vec2f {
public:
// CONSTRUCTORS & DESTRUCTOR
Vec2f() { data[0] = data[1] = 0; }
Vec2f(const Vec2f &V) {
data[0] = V.data[0];
data[1] = V.data[1]; }
Vec2f(float d0, float d1) {
data[0] = d0;
data[1] = d1; }
Vec2f(const Vec2f &V1, const Vec2f &V2) {
data[0] = V1.data[0] - V2.data[0];
data[1] = V1.data[1] - V2.data[1]; }
~Vec2f() { }
// ACCESSORS
void Get(float &d0, float &d1) const {
d0 = data[0];
d1 = data[1]; }
float operator[](int i) const {
assert (i >= 0 && i < 2);
return data[i]; }
float x() const { return data[0]; }
float y() const { return data[1]; }
float Length() const {
float l = (float)sqrt( data[0] * data[0] + data[1] * data[1] );
return l; }
// MODIFIERS
void Set(float d0, float d1) {
data[0] = d0;
data[1] = d1; }
void Scale(float d0, float d1) {
data[0] *= d0;
data[1] *= d1; }
void Divide(float d0, float d1) {
data[0] /= d0;
data[1] /= d1; }
void Negate() {
data[0] = -data[0];
data[1] = -data[1]; }
// OVERLOADED OPERATORS
Vec2f& operator=(const Vec2f &V) {
data[0] = V.data[0];
data[1] = V.data[1];
return *this; }
int operator==(const Vec2f &V) const {
return ((data[0] == V.data[0]) &&
(data[1] == V.data[1])); }
int operator!=(const Vec2f &V) {
return ((data[0] != V.data[0]) ||
(data[1] != V.data[1])); }
Vec2f& operator+=(const Vec2f &V) {
data[0] += V.data[0];
data[1] += V.data[1];
return *this; }
Vec2f& operator-=(const Vec2f &V) {
data[0] -= V.data[0];
data[1] -= V.data[1];
return *this; }
Vec2f& operator*=(float f) {
data[0] *= f;
data[1] *= f;
return *this; }
Vec2f& operator/=(float f) {
data[0] /= f;
data[1] /= f;
return *this; }
// OPERATIONS
float Dot2(const Vec2f &V) const {
return data[0] * V.data[0] + data[1] * V.data[1] ; }
// STATIC OPERATIONS
static void Add(Vec2f &a, const Vec2f &b, const Vec2f &c ) {
a.data[0] = b.data[0] + c.data[0];
a.data[1] = b.data[1] + c.data[1]; }
static void Sub(Vec2f &a, const Vec2f &b, const Vec2f &c ) {
a.data[0] = b.data[0] - c.data[0];
a.data[1] = b.data[1] - c.data[1]; }
static void CopyScale(Vec2f &a, const Vec2f &b, float c ) {
a.data[0] = b.data[0] * c;
a.data[1] = b.data[1] * c; }
static void AddScale(Vec2f &a, const Vec2f &b, const Vec2f &c, float d ) {
a.data[0] = b.data[0] + c.data[0] * d;
a.data[1] = b.data[1] + c.data[1] * d; }
static void Average(Vec2f &a, const Vec2f &b, const Vec2f &c ) {
a.data[0] = (b.data[0] + c.data[0]) * 0.5f;
a.data[1] = (b.data[1] + c.data[1]) * 0.5f; }
static void WeightedSum(Vec2f &a, const Vec2f &b, float c, const Vec2f &d, float e ) {
a.data[0] = b.data[0] * c + d.data[0] * e;
a.data[1] = b.data[1] * c + d.data[1] * e; }
// INPUT / OUTPUT
void Write(FILE *F = stdout) {
fprintf (F, "%f %f\n",data[0],data[1]); }
private:
// REPRESENTATION
float data[2];
};
// ====================================================================
// ====================================================================
class Vec3f {
public:
// CONSTRUCTORS & DESTRUCTOR
Vec3f() { data[0] = data[1] = data[2] = 0; }
Vec3f(const Vec3f &V) {
data[0] = V.data[0];
data[1] = V.data[1];
data[2] = V.data[2]; }
Vec3f(float d0, float d1, float d2) {
data[0] = d0;
data[1] = d1;
data[2] = d2; }
Vec3f(const Vec3f &V1, const Vec3f &V2) {
data[0] = V1.data[0] - V2.data[0];
data[1] = V1.data[1] - V2.data[1];
data[2] = V1.data[2] - V2.data[2]; }
~Vec3f() { }
// ACCESSORS
void Get(float &d0, float &d1, float &d2) const {
d0 = data[0];
d1 = data[1];
d2 = data[2]; }
float operator[](int i) const {
assert (i >= 0 && i < 3);
return data[i]; }
float x() const { return data[0]; }
float y() const { return data[1]; }
float z() const { return data[2]; }
float r() const { return data[0]; }
float g() const { return data[1]; }
float b() const { return data[2]; }
float Length() const {
float l = (float)sqrt( data[0] * data[0] +
data[1] * data[1] +
data[2] * data[2] );
return l; }
// MODIFIERS
void Set(float d0, float d1, float d2) {
data[0] = d0;
data[1] = d1;
data[2] = d2; }
void Scale(float d0, float d1, float d2) {
data[0] *= d0;
data[1] *= d1;
data[2] *= d2; }
void Divide(float d0, float d1, float d2) {
data[0] /= d0;
data[1] /= d1;
data[2] /= d2; }
void Normalize() {
float l = Length();
if (l > 0) {
data[0] /= l;
data[1] /= l;
data[2] /= l; }}
void Negate() {
data[0] = -data[0];
data[1] = -data[1];
data[2] = -data[2]; }
// OVERLOADED OPERATORS
Vec3f& operator=(const Vec3f &V) {
data[0] = V.data[0];
data[1] = V.data[1];
data[2] = V.data[2];
return *this; }
int operator==(const Vec3f &V) {
return ((data[0] == V.data[0]) &&
(data[1] == V.data[1]) &&
(data[2] == V.data[2])); }
int operator!=(const Vec3f &V) {
return ((data[0] != V.data[0]) ||
(data[1] != V.data[1]) ||
(data[2] != V.data[2])); }
Vec3f& operator+=(const Vec3f &V) {
data[0] += V.data[0];
data[1] += V.data[1];
data[2] += V.data[2];
return *this; }
Vec3f& operator-=(const Vec3f &V) {
data[0] -= V.data[0];
data[1] -= V.data[1];
data[2] -= V.data[2];
return *this; }
Vec3f& operator*=(int i) {
data[0] = float(data[0] * i);
data[1] = float(data[1] * i);
data[2] = float(data[2] * i);
return *this; }
Vec3f& operator*=(float f) {
data[0] *= f;
data[1] *= f;
data[2] *= f;
return *this; }
Vec3f& operator/=(int i) {
data[0] = float(data[0] / i);
data[1] = float(data[1] / i);
data[2] = float(data[2] / i);
return *this; }
Vec3f& operator/=(float f) {
data[0] /= f;
data[1] /= f;
data[2] /= f;
return *this; }
friend Vec3f operator+(const Vec3f &v1, const Vec3f &v2) {
Vec3f v3; Add(v3,v1,v2); return v3; }
friend Vec3f operator-(const Vec3f &v1, const Vec3f &v2) {
Vec3f v3; Sub(v3,v1,v2); return v3; }
friend Vec3f operator*(const Vec3f &v1, float f) {
Vec3f v2; CopyScale(v2,v1,f); return v2; }
// OPERATIONS
float Dot3(const Vec3f &V) const {
return data[0] * V.data[0] +
data[1] * V.data[1] +
data[2] * V.data[2] ; }
// STATIC OPERATIONS
friend void Add(Vec3f &a, const Vec3f &b, const Vec3f &c ) {
a.data[0] = b.data[0] + c.data[0];
a.data[1] = b.data[1] + c.data[1];
a.data[2] = b.data[2] + c.data[2]; }
friend void Sub(Vec3f &a, const Vec3f &b, const Vec3f &c ) {
a.data[0] = b.data[0] - c.data[0];
a.data[1] = b.data[1] - c.data[1];
a.data[2] = b.data[2] - c.data[2]; }
friend void CopyScale(Vec3f &a, const Vec3f &b, float c ) {
a.data[0] = b.data[0] * c;
a.data[1] = b.data[1] * c;
a.data[2] = b.data[2] * c; }
friend void AddScale(Vec3f &a, const Vec3f &b, const Vec3f &c, float d ) {
a.data[0] = b.data[0] + c.data[0] * d;
a.data[1] = b.data[1] + c.data[1] * d;
a.data[2] = b.data[2] + c.data[2] * d; }
friend void Average(Vec3f &a, const Vec3f &b, const Vec3f &c ) {
a.data[0] = (b.data[0] + c.data[0]) * 0.5f;
a.data[1] = (b.data[1] + c.data[1]) * 0.5f;
a.data[2] = (b.data[2] + c.data[2]) * 0.5f; }
friend void WeightedSum(Vec3f &a, const Vec3f &b, float c, const Vec3f &d, float e ) {
a.data[0] = b.data[0] * c + d.data[0] * e;
a.data[1] = b.data[1] * c + d.data[1] * e;
a.data[2] = b.data[2] * c + d.data[2] * e; }
static void Cross3(Vec3f &c, const Vec3f &v1, const Vec3f &v2) {
float x = v1.data[1]*v2.data[2] - v1.data[2]*v2.data[1];
float y = v1.data[2]*v2.data[0] - v1.data[0]*v2.data[2];
float z = v1.data[0]*v2.data[1] - v1.data[1]*v2.data[0];
c.data[0] = x; c.data[1] = y; c.data[2] = z; }
// INPUT / OUTPUT
void Write(FILE *F = stdout) {
fprintf (F, "%f %f %f\n",data[0],data[1],data[2]); }
private:
// REPRESENTATION
float data[3];
};
// ====================================================================
// ====================================================================
class Vec4f {
public:
// CONSTRUCTORS & DESTRUCTOR
Vec4f() { data[0] = data[1] = data[2] = data[3] = 0; }
Vec4f(const Vec4f &V) {
data[0] = V.data[0];
data[1] = V.data[1];
data[2] = V.data[2];
data[3] = V.data[3]; }
Vec4f(float d0, float d1, float d2, float d3) {
data[0] = d0;
data[1] = d1;
data[2] = d2;
data[3] = d3; }
Vec4f(const Vec3f &V, float w) {
data[0] = V.x();
data[1] = V.y();
data[2] = V.z();
data[3] = w; }
Vec4f(const Vec4f &V1, const Vec4f &V2) {
data[0] = V1.data[0] - V2.data[0];
data[1] = V1.data[1] - V2.data[1];
data[2] = V1.data[2] - V2.data[2];
data[3] = V1.data[3] - V2.data[3]; }
~Vec4f() { }
// ACCESSORS
void Get(float &d0, float &d1, float &d2, float &d3) const {
d0 = data[0];
d1 = data[1];
d2 = data[2];
d3 = data[3]; }
float operator[](int i) const {
assert (i >= 0 && i < 4);
return data[i]; }
float x() const { return data[0]; }
float y() const { return data[1]; }
float z() const { return data[2]; }
float w() const { return data[3]; }
float r() const { return data[0]; }
float g() const { return data[1]; }
float b() const { return data[2]; }
float a() const { return data[3]; }
float Length() const {
float l = (float)sqrt( data[0] * data[0] +
data[1] * data[1] +
data[2] * data[2] +
data[3] * data[3] );
return l; }
// MODIFIERS
void Set(float d0, float d1, float d2, float d3) {
data[0] = d0;
data[1] = d1;
data[2] = d2;
data[3] = d3; }
void Scale(float d0, float d1, float d2, float d3) {
data[0] *= d0;
data[1] *= d1;
data[2] *= d2;
data[3] *= d3; }
void Divide(float d0, float d1, float d2, float d3) {
data[0] /= d0;
data[1] /= d1;
data[2] /= d2;
data[3] /= d3; }
void Negate() {
data[0] = -data[0];
data[1] = -data[1];
data[2] = -data[2];
data[3] = -data[3]; }
void Normalize() {
float l = Length();
if (l > 0) {
data[0] /= l;
data[1] /= l;
data[2] /= l; }}
void DivideByW() {
if (data[3] != 0) {
data[0] /= data[3];
data[1] /= data[3];
data[2] /= data[3];
} else {
data[0] = data[1] = data[2] = 0; }
data[3] = 1;}
// OVERLOADED OPERATORS
Vec4f& operator=(const Vec4f &V) {
data[0] = V.data[0];
data[1] = V.data[1];
data[2] = V.data[2];
data[3] = V.data[3];
return *this; }
int operator==(const Vec4f &V) const {
return ((data[0] == V.data[0]) &&
(data[1] == V.data[1]) &&
(data[2] == V.data[2]) &&
(data[3] == V.data[3])); }
int operator!=(const Vec4f &V) const {
return ((data[0] != V.data[0]) ||
(data[1] != V.data[1]) ||
(data[2] != V.data[2]) ||
(data[3] != V.data[3])); }
Vec4f& operator+=(const Vec4f &V) {
data[0] += V.data[0];
data[1] += V.data[1];
data[2] += V.data[2];
data[3] += V.data[3];
return *this; }
Vec4f& operator-=(const Vec4f &V) {
data[0] -= V.data[0];
data[1] -= V.data[1];
data[2] -= V.data[2];
data[3] -= V.data[3];
return *this; }
Vec4f& operator*=(float f) {
data[0] *= f;
data[1] *= f;
data[2] *= f;
data[3] *= f;
return *this; }
Vec4f& operator/=(float f) {
data[0] /= f;
data[1] /= f;
data[2] /= f;
data[3] /= f;
return *this; }
// OPERATIONS
float Dot2(const Vec4f &V) const {
return data[0] * V.data[0] +
data[1] * V.data[1]; }
float Dot3(const Vec4f &V) const {
return data[0] * V.data[0] +
data[1] * V.data[1] +
data[2] * V.data[2]; }
float Dot4(const Vec4f &V) const {
return data[0] * V.data[0] +
data[1] * V.data[1] +
data[2] * V.data[2] +
data[3] * V.data[3]; }
// STATIC OPERATIONS
static void Add(Vec4f &a, const Vec4f &b, const Vec4f &c ) {
a.data[0] = b.data[0] + c.data[0];
a.data[1] = b.data[1] + c.data[1];
a.data[2] = b.data[2] + c.data[2];
a.data[3] = b.data[3] + c.data[3]; }
static void Sub(Vec4f &a, const Vec4f &b, const Vec4f &c ) {
a.data[0] = b.data[0] - c.data[0];
a.data[1] = b.data[1] - c.data[1];
a.data[2] = b.data[2] - c.data[2];
a.data[3] = b.data[3] - c.data[3]; }
static void CopyScale(Vec4f &a, const Vec4f &b, float c ) {
a.data[0] = b.data[0] * c;
a.data[1] = b.data[1] * c;
a.data[2] = b.data[2] * c;
a.data[3] = b.data[3] * c; }
static void AddScale(Vec4f &a, const Vec4f &b, const Vec4f &c, float d ) {
a.data[0] = b.data[0] + c.data[0] * d;
a.data[1] = b.data[1] + c.data[1] * d;
a.data[2] = b.data[2] + c.data[2] * d;
a.data[3] = b.data[3] + c.data[3] * d; }
static void Average(Vec4f &a, const Vec4f &b, const Vec4f &c ) {
a.data[0] = (b.data[0] + c.data[0]) * 0.5f;
a.data[1] = (b.data[1] + c.data[1]) * 0.5f;
a.data[2] = (b.data[2] + c.data[2]) * 0.5f;
a.data[3] = (b.data[3] + c.data[3]) * 0.5f; }
static void WeightedSum(Vec4f &a, const Vec4f &b, float c, const Vec4f &d, float e ) {
a.data[0] = b.data[0] * c + d.data[0] * e;
a.data[1] = b.data[1] * c + d.data[1] * e;
a.data[2] = b.data[2] * c + d.data[2] * e;
a.data[3] = b.data[3] * c + d.data[3] * e; }
static void Cross3(Vec4f &c, const Vec4f &v1, const Vec4f &v2) {
float x = v1.data[1]*v2.data[2] - v1.data[2]*v2.data[1];
float y = v1.data[2]*v2.data[0] - v1.data[0]*v2.data[2];
float z = v1.data[0]*v2.data[1] - v1.data[1]*v2.data[0];
c.data[0] = x; c.data[1] = y; c.data[2] = z; }
// INPUT / OUTPUT
void Write(FILE *F = stdout) {
fprintf (F, "%f %f %f %f\n",data[0],data[1],data[2],data[3]); }
private:
friend class Matrix;
// REPRESENTATION
float data[4];
};
inline ostream &operator<<(ostream &os, const Vec3f &v) {
os << "Vec3f <" <";
return os;
}
// ====================================================================
// ====================================================================
#endif