charles/src/basics/vector.cc
Eryn Wells 620d5a5bc6 Fill in missing Vector4 symbols
Add assignment and call operators, bool operators, etc
2014-08-10 11:38:55 -07:00

389 lines
5.3 KiB
C++

/* vector.cc
* vim: set tw=80:
* Eryn Wells <eryn@erynwells.me>
*/
#include <cmath>
#include <cstring>
#include <sstream>
#include <stdexcept>
#include "basics/vector.hh"
#include "basics/util.hh"
namespace charles {
namespace basics {
#pragma mark Constructors and Assignment
/*
* charles::basics::Vector4::Vector4 --
*/
Vector4::Vector4()
{
bzero(mData, sizeof(Double) * 4);
}
/*
* charles::basics::Vector4::Vector4 --
*/
Vector4::Vector4(Double x,
Double y,
Double z)
{
mData[0] = x;
mData[1] = y;
mData[2] = z;
mData[3] = 1.0;
}
/*
* charles::basics::Vector4::operator= --
*/
Vector4&
Vector4::operator=(const Vector4 &rhs)
{
memcpy(mData, rhs.mData, sizeof(Double) * 4);
return *this;
}
#pragma mark Component Access
/*
* charles::basics::Vector4::X --
*/
Double&
Vector4::X()
{
return mData[0];
}
/*
* charles::basics::Vector4::X --
*/
Double
Vector4::X()
const
{
return mData[0];
}
/*
* charles::basics::Vector4::Y --
*/
Double&
Vector4::Y()
{
return mData[1];
}
/*
* charles::basics::Vector4::Y --
*/
Double
Vector4::Y()
const
{
return mData[1];
}
/*
* charles::basics::Vector4::Z --
*/
Double&
Vector4::Z()
{
return mData[2];
}
/*
* charles::basics::Vector4::Z --
*/
Double
Vector4::Z()
const
{
return mData[2];
}
Double&
Vector4::operator()(UInt i)
{
if (i >= 4) {
std::stringstream ss;
ss << "vector index out of bounds: i = " << i;
throw std::out_of_range(ss.str());
}
return mData[i];
}
Double
Vector4::operator()(UInt i)
const
{
if (i >= 4) {
std::stringstream ss;
ss << "vector index out of bounds: i = " << i;
throw std::out_of_range(ss.str());
}
return mData[i];
}
/*
* charles::basics::Vector4::CArray --
*/
const Double*
Vector4::CArray()
const
{
return mData;
}
#pragma mark Boolean Operators
/*
* charles::basics::Vector4::operator== --
*/
bool
Vector4::operator==(const Vector4 &rhs)
const
{
for (UInt i = 0; i < 4; i++) {
if (!NearlyEqual(mData[i], rhs.mData[i])) {
return false;
}
}
return true;
}
/*
* charles::basics::Vector4::operator!= --
*/
bool
Vector4::operator!=(const Vector4 &rhs)
const
{
return !(*this == rhs);
}
#pragma mark Maths
/*
* charles::basics::Vector4::operator* --
*/
Vector4
Vector4::operator*(Double rhs)
const
{
return Vector4(*this) *= rhs;
}
/*
* charles::basics::Vector4::operator* --
*/
Vector4
Vector4::operator/(Double rhs)
const
{
return Vector4(*this) /= rhs;
}
/*
* charles::basics::Vector4::operator*= --
*/
Vector4&
Vector4::operator*=(Double rhs)
{
for (int i = 0; i < 4; i++) {
mData[i] *= rhs;
}
return *this;
}
/*
* charles::basics::Vector4::operator/= --
*/
Vector4&
Vector4::operator/=(Double rhs)
{
return *this *= (1.0 / rhs);
}
/*
* charles::basics::Vector4::operator+ --
*/
Vector4
Vector4::operator+(const Vector4 &rhs)
const
{
return Vector4(*this) += rhs;
}
/*
* charles::basics::Vector4::operator- --
*/
Vector4
Vector4::operator-(const Vector4 &rhs)
const
{
return Vector4(*this) -= rhs;
}
/*
* charles::basics::Vector4::operator+= --
*/
Vector4&
Vector4::operator+=(const Vector4 &rhs)
{
mData[0] += rhs.mData[0];
mData[1] += rhs.mData[1];
mData[2] += rhs.mData[2];
return *this;
}
/*
* charles::basics::Vector4::operator-= --
*/
Vector4&
Vector4::operator-=(const Vector4 &rhs)
{
return *this += -rhs;
}
/*
* charles::basics::Vector4::operator- --
*/
Vector4
Vector4::operator-()
const
{
return Vector4(-X(), -Y(), -Z());
}
/*
* charles::basics::Vector4::Length2 --
*/
Double
Vector4::Length2()
const
{
return X()*X() + Y()*Y() + Z()*Z();
}
/*
* charles::basics::Vector4::Length --
*/
Double
Vector4::Length()
const
{
return std::sqrt(Length2());
}
/*
* charles::basics::Vector4::Dot --
*/
Double
Vector4::Dot(const Vector4& rhs)
const
{
return X()*rhs.X() + Y()*rhs.Y() + Z()*rhs.Z();
}
/*
* charles::basics::Vector4::Cross --
*/
Vector4
Vector4::Cross(const Vector4& rhs)
const
{
return Vector4(mData[1]*rhs.mData[2] - mData[2]*rhs.mData[1],
mData[2]*rhs.mData[0] - mData[0]*rhs.mData[2],
mData[0]*rhs.mData[1] - mData[1]*rhs.mData[0]);
}
/*
* charles::basics::Vector4::Normalize --
*/
Vector4&
Vector4::Normalize()
{
return *this /= Length();
}
/*
* charles::basics::operator* --
*/
Vector4
operator*(Double lhs,
const Vector4& rhs)
{
return rhs * lhs;
}
/*
* charles::basics::Normalized --
*/
Vector4
Normalized(Vector4 v)
{
return v.Normalize();
}
/*
* charles::basics::LinearCombination --
*/
Vector4
LinearCombination(const Double k1, const Vector4& v1,
const Double k2, const Vector4& v2,
const Double k3, const Vector4& v3)
{
return Vector4(k1 * v1.X() + k2 * v2.X() + k3 * v3.X(),
k1 * v1.Y() + k2 * v2.Y() + k3 * v3.Y(),
k1 * v1.Z() + k2 * v2.Z() + k3 * v3.Z());
}
/*
* charles::basics::operator<< --
*/
std::ostream&
operator<<(std::ostream& os, const Vector4& v)
{
// Stream the vector like this: <x, y, z>
os << "<" << v.X() << ", " << v.Y() << ", " << v.Z() << ">";
return os;
}
} /* namespace basics */
} /* namespace charles */