#ifndef MXVECTOR_INCLUDED // -*- C++ -*- #define MXVECTOR_INCLUDED #if !defined(__GNUC__) # pragma once #endif /************************************************************************ Generic n-dimensional vector class Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. $Id: MxVector.h,v 1.9 1998/10/28 16:16:06 garland Exp $ ************************************************************************/ #include "MxMath.h" #ifdef __T #undef __T #endif #define __T float #include "mixvops.h" #define __T double #include "mixvops.h" //////////////////////////////////////////////////////////////////////// // // MxVBlock -- fixed-size vector class template // // The idea here is that we want a small collection of vector classes, // {2,3,4}D say, and we want *zero* space overhead. No length fields, // no vtables, just N numerical values. // template class MxVBlock { private: T elt[N]; protected: inline void copy(const MxVBlock& v) { for(uint i=0; i& v) { mxv_set(elt, v, N); } MxVBlock(const T *v) { mxv_set(elt, v, N); } inline unsigned int dim() const { return N; } T& operator()(uint i) { AssertBound(i& operator=(const MxVBlock& v) { mxv_set(elt, v, N); return *this; } inline MxVBlock& operator+=(const MxVBlock& v) { mxv_addinto(elt, v, N); return *this; } inline MxVBlock& operator-=(const MxVBlock& v) { mxv_subfrom(elt, v, N); return *this; } inline MxVBlock& operator*=(T s) { mxv_scale(elt,s,N); return *this; } inline MxVBlock& operator/=(T s) {mxv_invscale(elt,s,N);return *this;} inline MxVBlock& negate() { mxv_neg(elt, N); return *this; } // Binary arithmetic methods // inline MxVBlock operator+(const MxVBlock& v) const { MxVBlock r; mxv_add(r, elt, v, N); return r; } inline MxVBlock operator-(const MxVBlock& v) const { MxVBlock r; mxv_sub(r, elt, v, N); return r; } inline MxVBlock operator*(T s) const { MxVBlock r; mxv_scale(r, elt, s, N); return r; } inline MxVBlock operator/(T s) const { MxVBlock r; mxv_invscale(r, elt, s, N); return r; } inline MxVBlock operator-() const { MxVBlock r; mxv_neg(r, elt, N); return r; } inline T operator*(const MxVBlock& v) const {return mxv_dot(elt,v,N);} // Comparison operators inline bool operator==(const MxVBlock& v) const { return mxv_equal(elt, v, N); } inline bool operator!=(const MxVBlock& v) const { return !mxv_equal(elt, v, N); } }; //////////////////////////////////////////////////////////////////////// // // MxVector -- arbitrarily sized vectors // // With MxVector vectors, we're willing to pay a little per-vector space // overhead to achieve greater flexibility without having to instantiate // a template class for every single dimension we care about. // #include "MxBlock.h" class MxVector : public MxBlock { public: MxVector(unsigned int n) : MxBlock(n) {mxv_set(*this,0.0,dim());} MxVector(const MxVector& v) : MxBlock(v.length()) { copy(v); } MxVector& operator=(const MxVector& v) { copy(v); return *this; } MxVector& operator=(double d) { mxv_set(*this, d, dim()); return *this; } unsigned int dim() const { return length(); } MxVector& operator+=(const MxVector& v) { mxv_addinto(*this, v, dim()); return *this; } MxVector& operator-=(const MxVector& v) { mxv_subfrom(*this, v, dim()); return *this; } MxVector& operator*=(double d) { mxv_scale(*this, d, dim()); return *this; } MxVector& operator/=(double d) { mxv_invscale(*this, d, dim()); return *this; } double operator*(const MxVector& v) const {return mxv_dot(*this,v,dim());} }; // Convenient wrappers for mixvops functionality // inline double norm(const MxVector& v) { return mxv_norm(v, v.dim()); } inline double norm2(const MxVector& v) { return mxv_dot(v, v, v.dim()); } inline double unitize(MxVector& v) { return mxv_unitize(v, v.dim()); } inline ostream& operator<<(ostream& out,const MxVector& v) { return mxv_write(out,v,v.dim()); } inline istream& operator>>(istream& in, MxVector& v) { return mxv_read(in, v, v.dim()); } // MXVECTOR_INCLUDED #endif