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); } */