Skip to content

Instantly share code, notes, and snippets.

@gszauer
Created June 6, 2013 00:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gszauer/5718437 to your computer and use it in GitHub Desktop.
Save gszauer/5718437 to your computer and use it in GitHub Desktop.
#include "Vector.h"
#include <cmath>
const Vector Vector::zero(0.0f, 0.0f, 0.0f);
const Vector Vector::one(1.0f, 1.0f, 1.0f);
const Vector Vector::forward(0.0f, 0.0f, 1.0f);
const Vector Vector::up(0.0f, 1.0f, 0.0f);
const Vector Vector::right(1.0f, 0.0f, 0.0f);
Vector::Vector(float X, float Y, float Z) : x(X), y(Y), z(Z), w(0.0f) {}
Vector::Vector(const Vector& v) {
x = v.x;
y = v.y;
z = v.z;
w = 0.0f;
}
Vector::~Vector() {}
Vector& Vector::operator=(const Vector& v) {
if (this == &v) return *this;
x = v.x;
y = v.y;
z = v.z;
w = 0.0f;
return *this;
}
Vector Vector::Normalized() {
float len = sqrtf(x * x + y * y + z * z);
return Vector(x / len, y / len, z / len);
}
void Vector::Normalize() {
float len = sqrtf(x * x + y * y + z * z);
x /= len;
y /= len;
z /= len;
}
float Vector::Magnitude() {
return sqrtf(x * x + y * y + z * z);
}
float Vector::SqrMagnitude() {
return (x * x + y * y + z * z);
}
Vector Vector::Cross(Vector& other) {
float X = y * other.z - z * other.y;
float Y = z * other.x - x * other.z;
float Z = x * other.y - y * other.x;
return Vector(X, Y, Z);
}
float Vector::Dot(Vector& other) {
return (x * other.x + y * other.y + z * other.z);
}
float Vector::Angle(Vector& other) { // Angle in degrees
return atan2f(Vector::Cross(*this, other).Magnitude() * -1.0f, Vector::Dot(*this, other) * -1.0f) / 3.14f * 180.0f + 180.0f;
}
Vector Vector::Lerp(Vector& from, Vector& to, float t) {
return from + ((Vector)(to - from) * t);
}
Vector Vector::Slerp(Vector& from, Vector& to, float t) {
float dot = Vector::Dot(from, to);
if (dot < -1.0f) dot = -1.0f;
if (dot > 1.0f) dot = 1.0f;
float theta = acosf(dot) * t;
Vector relative = (to - (from * dot));
relative.Normalize();
return ((Vector)(from * cosf(theta)) + (Vector)(relative * sinf(theta)));
}
void Vector::OrthoNormalize(Vector* normal, Vector* tangent) {
normal->Normalize();
Vector norm = *normal;
Vector tan = tangent->Normalized();
*tangent = tan - (norm * Vector::Dot(norm, tan));
tangent->Normalize();
}
void Vector::OrthoNormalize(Vector* normal, Vector* tangent, Vector* binormal) {
Vector norm, tan, binorm;
normal->Normalize();
norm = *normal;
tan = tangent->Normalized();
Vector temp = Vector::Cross(norm, tan);
*tangent = Vector::Cross(temp, norm);
tangent->Normalize();
*binormal = Vector::Cross(norm, *tangent);
binormal->Normalize();
}
Vector Vector::Project(Vector& vector, Vector& onNormal) {
Vector theNormal = onNormal.Normalized();
return theNormal * Vector::Dot(vector, theNormal);
}
Vector Vector::Cross(Vector& lhs, Vector& rhs) {
float X = lhs.y * rhs.z - lhs.z * rhs.y;
float Y = lhs.z * rhs.x - lhs.x * rhs.z;
float Z = lhs.x * rhs.y - lhs.y * rhs.x;
return Vector(X, Y, Z);
}
float Vector::Dot(Vector& lhs, Vector& rhs) {
return (lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z);
}
float Vector::Distance(Vector& v1, Vector& v2) {
Vector r = v2 - v1;
return sqrtf(r.x * r.x + r.y * r.y + r.z * r.z);
}
float Vector::SqrDistance(Vector& v1, Vector& v2) {
Vector r = v2 - v1;
return (r.x * r.x + r.y * r.y + r.z * r.z);
}
float Vector::Angle(Vector& lhs, Vector& rhs) {
return lhs.Angle(rhs);
}
Vector Vector::Min(Vector& lhs, Vector& rhs) {
float X = (lhs.x < rhs.x)? lhs.x : rhs.x;
float Y = (lhs.y < rhs.y)? lhs.y : rhs.y;
float Z = (lhs.z < rhs.z)? lhs.z : rhs.z;
return Vector(X, Y, Z);
}
Vector Vector::Max(Vector& lhs, Vector& rhs) {
float X = (lhs.x < rhs.x)? rhs.x : lhs.x;
float Y = (lhs.y < rhs.y)? rhs.y : lhs.y;
float Z = (lhs.z < rhs.z)? rhs.z : lhs.z;
return Vector(X, Y, Z);
}
Vector& Vector::operator+=(Vector& rhs) {
x += rhs.x;
y += rhs.y;
z += rhs.z;
return *this;
}
Vector& Vector::operator-=(Vector& rhs) {
x -= rhs.x;
y -= rhs.y;
z -= rhs.z;
return *this;
}
Vector& Vector::operator*=(Vector& rhs) {
x *= rhs.x;
y *= rhs.y;
z *= rhs.z;
return *this;
}
Vector& Vector::operator*=(float rhs) {
x *= rhs;
y *= rhs;
z *= rhs;
return *this;
}
Vector Vector::operator+(Vector& rhs) {
return Vector(x + rhs.x, y + rhs.y, z + rhs.z);
}
Vector Vector::operator-(Vector& rhs) {
return Vector(x - rhs.x, y - rhs.y, z - rhs.z);
}
Vector Vector::operator*(Vector& rhs) {
return Vector(x * rhs.x, y * rhs.y, z * rhs.z);
}
Vector Vector::operator*(float rhs) {
return Vector(x * rhs, y * rhs, z * rhs);
}
bool Vector::operator==(Vector& rhs) {
return (x == rhs.x && y == rhs.y && z == rhs.z);
}
bool Vector::operator!=(Vector& rhs) {
return !(x == rhs.x && y == rhs.y && z == rhs.z);
}
Vector& Vector::operator+=(const Vector& rhs) {
x += rhs.x;
y += rhs.y;
z += rhs.z;
return *this;
}
Vector& Vector::operator-=(const Vector& rhs) {
x -= rhs.x;
y -= rhs.y;
z -= rhs.z;
return *this;
}
Vector& Vector::operator*=(const Vector& rhs) {
x *= rhs.x;
y *= rhs.y;
z *= rhs.z;
return *this;
}
const Vector Vector::operator+(const Vector& rhs) {
return Vector(x + rhs.x, y + rhs.y, z + rhs.z);
}
const Vector Vector::operator-(const Vector& rhs) {
return Vector(x - rhs.x, y - rhs.y, z - rhs.z);
}
const Vector Vector::operator*(const Vector& rhs) {
return Vector(x * rhs.x, y * rhs.y, z * rhs.z);
}
bool Vector::operator==(const Vector& rhs) {
return (x == rhs.x && y == rhs.y && z == rhs.z);
}
bool Vector::operator!=(const Vector& rhs) {
return !(x == rhs.x && y == rhs.y && z == rhs.z);
}
bool operator==(const Vector& lhs, const Vector& rhs) {
return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
}
bool operator!=(const Vector& lhs, const Vector& rhs) {
return !(lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
}
const Vector operator*(float lhs, const Vector& rhs) {
return Vector(rhs.x * lhs, rhs.y * lhs, rhs.y * lhs);
}
Vector operator*(float lhs, Vector& rhs) {
return Vector(rhs.x * lhs, rhs.y * lhs, rhs.y * lhs);
}
#ifndef _H_VECTOR_
#define _H_VECTOR_
class Vector {
public:
union {
struct {
float x;
float y;
float z;
float w;
};
float v[4];
};
public:
Vector(float X = 0.0f, float Y = 0.0f, float Z = 0.0f);
Vector(const Vector& v);
~Vector();
Vector& operator=(const Vector& v);
Vector Normalized();
void Normalize();
float Magnitude();
float SqrMagnitude();
Vector Cross(Vector& other);
float Dot(Vector& other);
float Angle(Vector& other);
static Vector Lerp(Vector& from, Vector& to, float t);
static Vector Slerp(Vector& from, Vector& to, float t);
static float Distance(Vector& v1, Vector& v2);
static float SqrDistance(Vector& v1, Vector& v2);
static void OrthoNormalize(Vector* normal, Vector* tangent);
static void OrthoNormalize(Vector* normal, Vector* tangent, Vector* binormal);
static Vector Project(Vector& vector, Vector& onNormal);
static Vector Cross(Vector& lhs, Vector& rhs);
static float Dot(Vector& lhs, Vector& rhs);
static float Angle(Vector& lhs, Vector& rhs);
static Vector Min(Vector& lhs, Vector& rhs);
static Vector Max(Vector& lhs, Vector& rhs);
Vector& operator+=(Vector& rhs);
Vector& operator-=(Vector& rhs);
Vector& operator*=(Vector& rhs);
Vector& operator*=(float rhs);
Vector operator+(Vector& rhs);
Vector operator-(Vector& rhs);
Vector operator*(Vector& rhs);
Vector operator*(float rhs);
bool operator==(Vector& rhs);
bool operator!=(Vector& rhs);
Vector& operator+=(const Vector& rhs);
Vector& operator-=(const Vector& rhs);
Vector& operator*=(const Vector& rhs);
const Vector operator+(const Vector& rhs);
const Vector operator-(const Vector& rhs);
const Vector operator*(const Vector& rhs);
bool operator==(const Vector& rhs);
bool operator!=(const Vector& rhs);
static const Vector zero;
static const Vector one;
static const Vector forward;
static const Vector up;
static const Vector right;
};
bool operator==(const Vector& lhs, const Vector& rhs);
bool operator!=(const Vector& lhs, const Vector& rhs);
const Vector operator*(float lhs, const Vector& rhs);
Vector operator*(float lhs, Vector& rhs);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment