Simple Vector Library 1.5 http://www.cs.cmu.edu/~ajw/doc/svl.html
Vec.cpp
- Committer:
- BartJanssens
- Date:
- 2016-01-05
- Revision:
- 1:e25ff4b06ed2
- Parent:
- 0:785cff1e5a7c
File content as of revision 1:e25ff4b06ed2:
/*
File: Vec.cpp
Function: Implements Vec.h
Author(s): Andrew Willmott
Copyright: (c) 1995-2001, Andrew Willmott
*/
#include "Vec.h"
//#include <cctype>
//#include <cstring>
#include <cstdarg>
//#include <iomanip>
#include "Vec2.h"
#include "Vec3.h"
#include "Vec4.h"
// --- Vec Constructors -------------------------------------------------------
Vec::Vec(Int n, ZeroOrOne k) : elts(n)
{
Assert(n > 0,"(Vec) illegal vector size");
data = new Real[n];
MakeBlock(k);
}
Vec::Vec(Int n, Axis a) : elts(n)
{
Assert(n > 0,"(Vec) illegal vector size");
data = new Real[n];
MakeUnit(a);
}
Vec::Vec(const Vec &v)
{
Assert(v.data != 0, "(Vec) Can't construct from a null vector");
elts = v.Elts();
data = new Real[elts];
#ifdef VL_USE_MEMCPY
memcpy(data, v.Ref(), sizeof(Real) * Elts());
#else
for (Int i = 0; i < Elts(); i++)
data[i] = v[i];
#endif
}
Vec::Vec(const Vec2 &v) : data(v.Ref()), elts(v.Elts() | VL_REF_FLAG)
{
}
Vec::Vec(const Vec3 &v) : data(v.Ref()), elts(v.Elts() | VL_REF_FLAG)
{
}
Vec::Vec(const Vec4 &v) : data(v.Ref()), elts(v.Elts() | VL_REF_FLAG)
{
}
Vec::Vec(Int n, double elt0, ...) : elts(n)
{
Assert(n > 0,"(Vec) illegal vector size");
va_list ap;
Int i = 1;
data = new Real[n];
va_start(ap, elt0);
SetReal(data[0], elt0);
while (--n)
SetReal(data[i++], va_arg(ap, double));
va_end(ap);
}
Vec::~Vec()
{
Assert(elts != 0,"(Vec) illegal vector size");
if (!IsRef())
delete[] data;
}
// --- Vec Assignment Operators -----------------------------------------------
Vec &Vec::operator = (const Vec &v)
{
if (!IsRef())
SetSize(v.Elts());
else
Assert(Elts() == v.Elts(), "(Vec::=) Vector sizes don't match");
#ifdef VL_USE_MEMCPY
memcpy(data, v.data, sizeof(Real) * Elts());
#else
for (Int i = 0; i < Elts(); i++)
data[i] = v[i];
#endif
return(SELF);
}
Vec &Vec::operator = (const Vec2 &v)
{
if (!IsRef())
SetSize(v.Elts());
else
Assert(Elts() == v.Elts(), "(Vec::=) Vector sizes don't match");
data[0] = v[0];
data[1] = v[1];
return(SELF);
}
Vec &Vec::operator = (const Vec3 &v)
{
if (!IsRef())
SetSize(v.Elts());
else
Assert(Elts() == v.Elts(), "(Vec::=) Vector sizes don't match");
data[0] = v[0];
data[1] = v[1];
data[2] = v[2];
return(SELF);
}
Vec &Vec::operator = (const Vec4 &v)
{
if (!IsRef())
SetSize(v.Elts());
else
Assert(Elts() == v.Elts(), "(Vec::=) Vector sizes don't match");
data[0] = v[0];
data[1] = v[1];
data[2] = v[2];
data[3] = v[3];
return(SELF);
}
Void Vec::SetSize(Int ni)
{
Assert(ni > 0, "(Vec::SetSize) Illegal vector size");
UInt n = UInt(ni);
if (!IsRef())
{
// Don't reallocate if we already have enough storage
if (n <= elts)
{
elts = n;
return;
}
// Otherwise, delete old storage
delete[] data;
elts = n;
data = new Real[elts];
}
else
Assert(false, "(Vec::SetSize) Can't resize a vector reference");
}
Vec &Vec::MakeZero()
{
#ifdef VL_USE_MEMCPY
memset(data, 0, sizeof(Real) * Elts());
#else
Int j;
for (j = 0; j < Elts(); j++)
data[j] = vl_zero;
#endif
return(SELF);
}
Vec &Vec::MakeUnit(Int i, Real k)
{
MakeZero();
data[i] = k;
return(SELF);
}
Vec &Vec::MakeBlock(Real k)
{
Int i;
for (i = 0; i < Elts(); i++)
data[i] = k;
return(SELF);
}
// --- Vec In-Place operators -------------------------------------------------
Vec &Vec::operator += (const Vec &b)
{
Assert(Elts() == b.Elts(), "(Vec::+=) vector sizes don't match");
Int i;
for (i = 0; i < Elts(); i++)
data[i] += b[i];
return(SELF);
}
Vec &Vec::operator -= (const Vec &b)
{
Assert(Elts() == b.Elts(), "(Vec::-=) vector sizes don't match");
Int i;
for (i = 0; i < Elts(); i++)
data[i] -= b[i];
return(SELF);
}
Vec &Vec::operator *= (const Vec &b)
{
Assert(Elts() == b.Elts(), "(Vec::*=) Vec sizes don't match");
Int i;
for (i = 0; i < Elts(); i++)
data[i] *= b[i];
return(SELF);
}
Vec &Vec::operator *= (Real s)
{
Int i;
for (i = 0; i < Elts(); i++)
data[i] *= s;
return(SELF);
}
Vec &Vec::operator /= (const Vec &b)
{
Assert(Elts() == b.Elts(), "(Vec::/=) Vec sizes don't match");
Int i;
for (i = 0; i < Elts(); i++)
data[i] /= b[i];
return(SELF);
}
Vec &Vec::operator /= (Real s)
{
Int i;
for (i = 0; i < Elts(); i++)
data[i] /= s;
return(SELF);
}
// --- Vec Comparison Operators -----------------------------------------------
Bool operator == (const Vec &a, const Vec &b)
{
Int i;
for (i = 0; i < a.Elts(); i++)
if (a[i] != b[i])
return(0);
return(1);
}
Bool operator != (const Vec &a, const Vec &b)
{
Int i;
for (i = 0; i < a.Elts(); i++)
if (a[i] != b[i])
return(1);
return(0);
}
// --- Vec Arithmetic Operators -----------------------------------------------
Vec operator + (const Vec &a, const Vec &b)
{
Assert(a.Elts() == b.Elts(), "(Vec::+) Vec sizes don't match");
Vec result(a.Elts());
Int i;
for (i = 0; i < a.Elts(); i++)
result[i] = a[i] + b[i];
return(result);
}
Vec operator - (const Vec &a, const Vec &b)
{
Assert(a.Elts() == b.Elts(), "(Vec::-) Vec sizes don't match");
Vec result(a.Elts());
Int i;
for (i = 0; i < a.Elts(); i++)
result[i] = a[i] - b[i];
return(result);
}
Vec operator - (const Vec &v)
{
Vec result(v.Elts());
Int i;
for (i = 0; i < v.Elts(); i++)
result[i] = - v[i];
return(result);
}
Vec operator * (const Vec &a, const Vec &b)
{
Assert(a.Elts() == b.Elts(), "(Vec::*) Vec sizes don't match");
Vec result(a.Elts());
Int i;
for (i = 0; i < a.Elts(); i++)
result[i] = a[i] * b[i];
return(result);
}
Vec operator * (const Vec &v, Real s)
{
Vec result(v.Elts());
Int i;
for (i = 0; i < v.Elts(); i++)
result[i] = v[i] * s;
return(result);
}
Vec operator / (const Vec &a, const Vec &b)
{
Assert(a.Elts() == b.Elts(), "(Vec::/) Vec sizes don't match");
Vec result(a.Elts());
Int i;
for (i = 0; i < a.Elts(); i++)
result[i] = a[i] / b[i];
return(result);
}
Vec operator / (const Vec &v, Real s)
{
Vec result(v.Elts());
Int i;
for (i = 0; i < v.Elts(); i++)
result[i] = v[i] / s;
return(result);
}
Real dot(const Vec &a, const Vec &b)
{
Assert(a.Elts() == b.Elts(), "(Vec::dot) Vec sizes don't match");
Real sum = vl_zero;
Int i;
for (i = 0; i < a.Elts(); i++)
sum += a[i] * b[i];
return(sum);
}
Vec operator * (Real s, const Vec &v)
{
Vec result(v.Elts());
Int i;
for (i = 0; i < v.Elts(); i++)
result[i] = v[i] * s;
return(result);
}
Vec &Vec::Clamp(Real fuzz)
// clamps all values of the matrix with a magnitude
// smaller than fuzz to zero.
{
Int i;
for (i = 0; i < Elts(); i++)
if (len(SELF[i]) < fuzz)
SELF[i] = vl_zero;
return(SELF);
}
Vec &Vec::Clamp()
{
return(Clamp(1e-7));
}
Vec clamped(const Vec &v, Real fuzz)
// clamps all values of the matrix with a magnitude
// smaller than fuzz to zero.
{
Vec result(v);
return(result.Clamp(fuzz));
}
Vec clamped(const Vec &v)
{
return(clamped(v, 1e-7));
}
// --- Vec Input & Output -----------------------------------------------------
/*
ostream &operator << (ostream &s, const Vec &v)
{
Int i, w;
s << '[';
if (v.Elts() > 0)
{
w = s.width();
s << v[0];
for (i = 1; i < v.Elts(); i++)
s << ' ' << setw(w) << v[i];
}
s << ']';
return(s);
}
*/
inline Void CopyPartialVec(const Vec &u, Vec &v, Int numElts)
{
for (Int i = 0; i < numElts; i++)
v[i] = u[i];
}
/*
istream &operator >> (istream &s, Vec &v)
{
Int size = 0;
Vec inVec(16);
Char c;
// Expected format: [a b c d ...]
while (isspace(s.peek())) // chomp white space
s.get(c);
if (s.peek() == '[')
{
s.get(c);
while (isspace(s.peek())) // chomp white space
s.get(c);
while (s.peek() != ']') // resize if needed
{
if (size == inVec.Elts())
{
Vec holdVec(inVec);
inVec.SetSize(size * 2);
CopyPartialVec(holdVec, inVec, size);
}
s >> inVec[size++]; // read an item
if (!s)
{
_Warning("Couldn't read vector element");
return(s);
}
while (isspace(s.peek())) // chomp white space
s.get(c);
}
s.get(c);
}
else
{
s.clear(ios::failbit);
_Warning("Error: Expected '[' while reading vector");
return(s);
}
v.SetSize(size);
CopyPartialVec(inVec, v, size);
return(s);
}
*/