/*
Vector.cpp
Written by Matthew Fisher
The Vec3 struct represents a 3-dimensional (x, y, z) real ordered triplet. It is used constantly everywhere.
The Vec4 struct represents a 4-dimensional (x, y, z, w) real ordered triplet. It is used mostly for matrix multiplication.
Most of the Vec3 and Vec4 functions and overloaded operators are self-explanitory and are not commented.
*/
#ifndef __SPACEVECTOR_CPP
#define __SPACEVECTOR_CPP
#include "Vector.h"
Vec3::Vec3()
{
}
Vec3::Vec3(float _x, float _y, float _z)
{
x = _x;
y = _y;
z = _z;
}
Vec3::Vec3(const Vec3 &V)
{
x = V.x;
y = V.y;
z = V.z;
}
Vec3::Vec3(const RGBColor &c)
{
x = c.r / 255.0f;
y = c.g / 255.0f;
z = c.b / 255.0f;
}
__forceinline Vec3& Vec3::operator = (const Vec3 &V)
{
x = V.x;
y = V.y;
z = V.z;
return *this;
}
__forceinline void Vec3::StdRandomVector()
{
x = float(rand()) / RAND_MAX * 2.0f - 1.0f;
y = float(rand()) / RAND_MAX * 2.0f - 1.0f;
z = float(rand()) / RAND_MAX * 2.0f - 1.0f;
}
__forceinline void Vec3::StdRandomNormal()
{
StdRandomVector();
Normalize();
}
__forceinline float Vec3::Length()
{
return sqrtf(x*x+y*y+z*z);
}
__forceinline float Vec3::LengthSq()
{
return x*x+y*y+z*z;
}
__forceinline void Vec3::Normalize()
{
float Len = Length();
//MyAssert(Len != 0.0f);
x /= Len;
y /= Len;
z /= Len;
}
__forceinline Vec3::operator D3DXVECTOR3() const
{
D3DXVECTOR3 V(x, y, z);
return V;
}
__forceinline void Vec3Cross(Vec3 &Target, const Vec3 &Left, const Vec3 &Right)
{
Vec3 Temp;
Temp.x = Left.y * Right.z - Left.z * Right.y;
Temp.y = Left.z * Right.x - Left.x * Right.z;
Temp.z = Left.x * Right.y - Left.y * Right.x;
Target = Temp;
}
__forceinline void Vec3TriNormal(Vec3 &Target, const Vec3 &V1, const Vec3 &V2, const Vec3 &V3)
{
Vec3 Diff1 = V2 - V1;
Vec3 Diff2 = V3 - V1;
Vec3Cross(Target, Diff1, Diff2);
Target.Normalize();
}
__forceinline float Vec3Dot(const Vec3 &Left, const Vec3 &Right)
{
return (Left.x * Right.x + Left.y * Right.y + Left.z * Right.z);
}
__forceinline void Vec3Lerp(Vec3 &Target, const Vec3 &Left, const Vec3 &Right, float s)
{
Target = Left + s * (Right - Left);
}
__forceinline void Vec3Maximize(Vec3 &Target, const Vec3 &Left, const Vec3 &Right)
{
Vec3 Target2 = Right;
if(Left.x > Right.x) Target2.x = Left.x;
if(Left.y > Right.y) Target2.y = Left.y;
if(Left.z > Right.z) Target2.z = Left.z;
Target = Target2;
}
__forceinline void Vec3Minimize(Vec3 &Target, const Vec3 &Left, const Vec3 &Right)
{
Vec3 Target2 = Right;
if(Left.x < Right.x) Target2.x = Left.x;
if(Left.y < Right.y) Target2.y = Left.y;
if(Left.z < Right.z) Target2.z = Left.z;
Target = Target2;
}
__forceinline Vec3 operator * (const Vec3 &Left, float Right)
{
Vec3 Return;
Return.x = Left.x * Right;
Return.y = Left.y * Right;
Return.z = Left.z * Right;
return Return;
}
__forceinline Vec3 operator * (float Right, const Vec3 &Left)
{
Vec3 Return;
Return.x = Left.x * Right;
Return.y = Left.y * Right;
Return.z = Left.z * Right;
return Return;
}
__forceinline Vec3 operator / (const Vec3 &Left, float Right)
{
Vec3 Return;
Return.x = Left.x / Right;
Return.y = Left.y / Right;
Return.z = Left.z / Right;
return Return;
}
__forceinline Vec3 operator + (const Vec3 &Left, const Vec3 &Right)
{
Vec3 Return;
Return.x = Left.x + Right.x;
Return.y = Left.y + Right.y;
Return.z = Left.z + Right.z;
return Return;
}
__forceinline Vec3 operator - (const Vec3 &Left, const Vec3 &Right)
{
Vec3 Return;
Return.x = Left.x - Right.x;
Return.y = Left.y - Right.y;
Return.z = Left.z - Right.z;
return Return;
}
__forceinline Vec3& Vec3::operator *= (float Right)
{
x *= Right;
y *= Right;
z *= Right;
return *this;
}
__forceinline Vec3& Vec3::operator /= (float Right)
{
x /= Right;
y /= Right;
z /= Right;
return *this;
}
__forceinline Vec3& Vec3::operator += (const Vec3 &Right)
{
x += Right.x;
y += Right.y;
z += Right.z;
return *this;
}
__forceinline Vec3& Vec3::operator -= (const Vec3 &Right)
{
x -= Right.x;
y -= Right.y;
z -= Right.z;
return *this;
}
Vec3 Vec3::ComponentSquare()
{
//return Vec3(x*x, y*y, z*z);
return Vec3(fabsf(x), fabsf(y), fabsf(z));
}
__forceinline Vec3 operator - (const Vec3 &V)
{
Vec3 Result;
Result.x = -V.x;
Result.y = -V.y;
Result.z = -V.z;
return Result;
}
Vec4::Vec4()
{
}
Vec4::Vec4(float _x, float _y, float _z, float _w)
{
x = _x;
y = _y;
z = _z;
w = _w;
}
Vec4::Vec4(const Vec4 &V)
{
x = V.x;
y = V.y;
z = V.z;
w = V.w;
}
Vec4& Vec4::operator = (const Vec4 &V)
{
x = V.x;
y = V.y;
z = V.z;
w = V.w;
return *this;
}
float Vec4::Length()
{
return sqrtf(x*x+y*y+z*z+w*w);
}
float Vec4::LengthSq()
{
return x*x+y*y+z*z+w*w;
}
void Vec4::Normalize()
{
float Len = Length();
x /= Len;
y /= Len;
z /= Len;
w /= Len;
}
float Vec4Dot(const Vec4 &Left, const Vec4 &Right)
{
return (Left.x * Right.x + Left.y * Right.y + Left.z * Right.z + Left.w * Right.w);
}
void Vec4Lerp(Vec4 &Target, const Vec4 &Left, const Vec4 &Right, float s)
{
Target = Left + s * (Right - Left);
}
void Vec4Maximize(Vec4 &Target, const Vec4 &Left, const Vec4 &Right)
{
Target = Right;
if(Left.x > Right.x) Target.x = Left.x;
if(Left.y > Right.y) Target.y = Left.y;
if(Left.z > Right.z) Target.z = Left.z;
if(Left.w > Right.w) Target.w = Left.w;
}
void Vec4Minimize(Vec4 &Target, const Vec4 &Left, const Vec4 &Right)
{
Target = Right;
if(Left.x < Right.x) Target.x = Left.x;
if(Left.y < Right.y) Target.y = Left.y;
if(Left.z < Right.z) Target.z = Left.z;
if(Left.w < Right.w) Target.w = Left.w;
}
Vec4 operator * (const Vec4 &Left, float Right)
{
Vec4 Return;
Return.x = Left.x * Right;
Return.y = Left.y * Right;
Return.z = Left.z * Right;
Return.w = Left.w * Right;
return Return;
}
Vec4 operator * (float Right, const Vec4 &Left)
{
Vec4 Return;
Return.x = Left.x * Right;
Return.y = Left.y * Right;
Return.z = Left.z * Right;
Return.w = Left.w * Right;
return Return;
}
Vec4 operator / (const Vec4 &Left, float Right)
{
Vec4 Return;
Return.x = Left.x / Right;
Return.y = Left.y / Right;
Return.z = Left.z / Right;
Return.w = Left.w / Right;
return Return;
}
Vec4 operator + (const Vec4 &Left, const Vec4 &Right)
{
Vec4 Return;
Return.x = Left.x + Right.x;
Return.y = Left.y + Right.y;
Return.z = Left.z + Right.z;
Return.w = Left.w + Right.w;
return Return;
}
Vec4 operator - (const Vec4 &Left, const Vec4 &Right)
{
Vec4 Return;
Return.x = Left.x - Right.x;
Return.y = Left.y - Right.y;
Return.z = Left.z - Right.z;
Return.w = Left.w - Right.w;
return Return;
}
Vec4& Vec4::operator *= (float Right)
{
x *= Right;
y *= Right;
z *= Right;
w *= Right;
return *this;
}
Vec4& Vec4::operator /= (float Right)
{
x /= Right;
y /= Right;
z /= Right;
w /= Right;
return *this;
}
Vec4& Vec4::operator += (const Vec4 &Right)
{
x += Right.x;
y += Right.y;
z += Right.z;
w += Right.w;
return *this;
}
Vec4& Vec4::operator -= (const Vec4 &Right)
{
x -= Right.x;
y -= Right.y;
z -= Right.z;
w -= Right.w;
return *this;
}
__forceinline Vec4 operator - (const Vec4 &V)
{
Vec4 Result;
Result.x = -V.x;
Result.y = -V.y;
Result.z = -V.z;
Result.w = -V.w;
return Result;
}
istream& operator >> (istream &is, Vec3 &v)
{
is >> v.x >> v.y >> v.z;
return is;
}
ostream& operator << (ostream &os, const Vec3 &v)
{
os << v.x << ' ' << v.y << ' ' << v.z;
return os;
}
ostream& operator << (ostream &os, const Vec4 &v)
{
os << v.x << ' ' << v.y << ' ' << v.z << ' ' << v.w;
return os;
}
float AngleBetween(const Vec3 &Left, const Vec3 &Right)
{
//the cosine of the angle between two vectors is the dot product of the two vectors after normalization
Vec3 V1 = Left, V2 = Right;
V1.Normalize();
V2.Normalize();
float Dot = Vec3Dot(V1, V2);
if(fabsf(Dot) >= 1.0f) Dot = 0.999f;
return acosf(Dot);
}
#endif
Top