// $Id$ /**************************************************************************** * Copyright (C) 2008 Adrien Saladin * * adrien.saladin@gmail.com * * * * 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 3 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, see . * * * ***************************************************************************/ #ifndef _COORDS_ARRAY_H_ #define _COORDS_ARRAY_H_ #include #include #include "coord3d.h" namespace PTools{ typedef std::vector VCoords; inline void matrix44xVect(const dbl mat[ 4 ][ 4 ], const Coord3D& vect, Coord3D& out ) { out.x = vect.x * mat[ 0 ][ 0 ] + vect.y * mat[ 0 ][ 1 ] + vect.z * mat[ 0 ][ 2 ] + mat[ 0 ][ 3 ] ; out.y = vect.x * mat[ 1 ][ 0 ] + vect.y * mat[ 1 ][ 1 ] + vect.z * mat[ 1 ][ 2 ] + mat[ 1 ][ 3 ] ; out.z = vect.x * mat[ 2 ][ 0 ] + vect.y * mat[ 2 ][ 1 ] + vect.z * mat[ 2 ][ 2 ] + mat[ 2 ][ 3 ] ; } class CoordsArray { private: //private data /* don't forget the constructors if you add some private data ! */ VCoords _refcoords; mutable VCoords _movedcoords; dbl mat44[4][4]; // 4x4 matrix mutable bool _uptodate ; mutable void (CoordsArray::*_getcoords)(const uint i, Coord3D& co) const; //C++ member function pointer. Points to a CoordArray function that takes a const uint and a Coord3D& and returns void. private: //private methods void _modified() { _uptodate = false; _getcoords = & CoordsArray::_safegetcoords; }; // call this function when _movedcoords needs an update before getting real coordinates void _safegetcoords(const uint i, Coord3D& co) const { assert(_refcoords.size() == _movedcoords.size()); for (uint j=0; j<_refcoords.size(); j++) { matrix44xVect(mat44, _refcoords[j], _movedcoords[j]); } _uptodate = true; //modify the function pointer _getcoords to call the "unsafe" method next time (faster) _getcoords = & CoordsArray::unsafeGetCoords; (*this.* _getcoords)(i, co); //return the correct function }; public: CoordsArray(); //constructor CoordsArray(const CoordsArray & ca); //copy constructor /// get the cached coordinates. You must ensure that update() has been called first ! void inline unsafeGetCoords(const uint i, Coord3D& co) const { co = _movedcoords[i];}; void AddCoord(const Coord3D& co) {_refcoords.push_back(co); _movedcoords.push_back(co); _modified(); }; uint Size() const {return _refcoords.size();}; void GetCoords(const uint i, Coord3D& co) const throw(std::out_of_range) ; void SetCoords(const uint k, const Coord3D& co); /// Translate the whole object void Translate(const Coord3D& tr); /// Euler Rotation void AttractEulerRotate(dbl phi, dbl ssi, dbl rot); void ResetMatrix(); std::string PrintMatrix() const; ///return the rotation/translation matrix Matrix GetMatrix() const; protected: void MatrixMultiply(const dbl mat[4][4]); }; } //namespace PTools #endif // _COORDS_ARRAY_H_