// Copyright (C) 2009 foam // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include #include #include #ifndef FOAM_VECTOR #define FOAM_VECTOR template bool feq(T a, T b, T t=0.001) { return fabs(a-b) class Vector { public: Vector(); Vector(unsigned int s); ~Vector(); Vector(const Vector &other); T &operator[](unsigned int i) { assert(i &other); Vector Normalised() const; Vector &operator=(const Vector &other); Vector operator+(const Vector &other) const; Vector operator-(const Vector &other) const; Vector operator+(T v) const; Vector operator-(T v) const; Vector operator*(T v) const; Vector operator/(T v) const; Vector &operator+=(const Vector &other); Vector &operator-=(const Vector &other); Vector &operator+=(T v); Vector &operator-=(T v); Vector &operator*=(T v); Vector &operator/=(T v); void Save(FILE *f) const; void Load(FILE *f); static void RunTests(); private: unsigned int m_Size; T *m_Data; }; template Vector::Vector() : m_Size(0) { m_Data=NULL; } template Vector::Vector(unsigned int s) : m_Size(s) { m_Data=new T[s]; } template Vector::~Vector() { delete[] m_Data; } template Vector::Vector(const Vector &other) { m_Size = other.m_Size; m_Data=new T[m_Size]; memcpy(m_Data,other.m_Data,m_Size*sizeof(T)); } template Vector &Vector::operator=(const Vector &other) { if (m_Data!=NULL) { delete[] m_Data; } m_Size = other.m_Size; m_Data=new T[m_Size]; memcpy(m_Data,other.m_Data,m_Size*sizeof(T)); return *this; } template void Vector::Print() const { for (unsigned int i=0; i void Vector::SetAll(T s) { for (unsigned int i=0; i bool Vector::IsInf() { for (unsigned int i=0; i T Vector::DistanceFrom(const Vector &other) const { assert(m_Size==other.m_Size); float acc=0; for (unsigned int i=0; i T Vector::Magnitude() const { float acc=0; for (unsigned int i=0; i T Vector::Dot(const Vector &other) { assert(m_Size==other.m_Size); T acc=0; for (unsigned int i=0; i Vector Vector::Normalised() const { Vector ret(*this); ret/=ret.Magnitude(); return ret; } template Vector Vector::operator+(const Vector &other) const { assert(m_Size==other.m_Size); Vector ret(m_Size); for (unsigned int i=0; i Vector Vector::operator-(const Vector &other) const { assert(m_Size==other.m_Size); Vector ret(m_Size); for (unsigned int i=0; i Vector Vector::operator+(T v) const { Vector ret(m_Size); for (unsigned int i=0; i Vector Vector::operator-(T v) const { Vector ret(m_Size); for (unsigned int i=0; i Vector Vector::operator*(T v) const { Vector ret(m_Size); for (unsigned int i=0; i Vector Vector::operator/(T v) const { Vector ret(m_Size); for (unsigned int i=0; i Vector &Vector::operator+=(const Vector &other) { assert(m_Size==other.m_Size); for (unsigned int i=0; i Vector &Vector::operator-=(const Vector &other) { assert(m_Size==other.m_Size); for (unsigned int i=0; i Vector &Vector::operator+=(T v) { for (unsigned int i=0; i Vector &Vector::operator-=(T v) { for (unsigned int i=0; i Vector &Vector::operator*=(T v) { for (unsigned int i=0; i Vector &Vector::operator/=(T v) { for (unsigned int i=0; i T Vector::Mean() { T acc=0; for (unsigned int i=0; i void Vector::Save(FILE* f) const { int version = 1; fwrite(&version,sizeof(version),1,f); fwrite(&m_Size,sizeof(m_Size),1,f); fwrite(m_Data,sizeof(T)*m_Size,1,f); } template void Vector::Load(FILE* f) { int version; fread(&version,sizeof(version),1,f); fread(&m_Size,sizeof(m_Size),1,f); m_Data=new T[m_Size]; fread(m_Data,sizeof(T)*m_Size,1,f); } template void Vector::RunTests() { Vector m(10); m.SetAll(0); assert(m[0]==0); m[5]=0.5; assert(m[5]==0.5); Vector om(m); assert(om[5]==0.5); assert(feq(m.Magnitude(),0.5f)); Vector a(10); a.Zero(); a[5]=-10; assert(feq(a.DistanceFrom(m),10.5f)); } #endif