worldsim/include/wvector.h

00001 /********************************************************************************
00002  *  WorldSim -- library for robot simulations                                   *
00003  *  Copyright (C) 2008-2011 Gianluca Massera <emmegian@yahoo.it>                *
00004  *                                                                              *
00005  *  This program is free software; you can redistribute it and/or modify        *
00006  *  it under the terms of the GNU General Public License as published by        *
00007  *  the Free Software Foundation; either version 2 of the License, or           *
00008  *  (at your option) any later version.                                         *
00009  *                                                                              *
00010  *  This program is distributed in the hope that it will be useful,             *
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of              *
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
00013  *  GNU General Public License for more details.                                *
00014  *                                                                              *
00015  *  You should have received a copy of the GNU General Public License           *
00016  *  along with this program; if not, write to the Free Software                 *
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  *
00018  ********************************************************************************/
00019 
00020 #ifndef WVECTOR_H
00021 #define WVECTOR_H
00022 
00023 #include "worldsimconfig.h"
00024 #include "qglviewer/vec.h"
00025 #include <cmath>
00026 
00027 namespace farsa {
00028 
00036 template <bool Shared>
00037 struct FARSA_WSIM_TEMPLATE InternalData
00038 {
00039     real data[4];
00040 };
00041 
00049 template <>
00050 struct FARSA_WSIM_TEMPLATE InternalData<true>
00051 {
00052 };
00053 
00068 template <bool Shared = false>
00069 class FARSA_WSIM_TEMPLATE wVectorT : protected InternalData<Shared> {
00070 public:
00072     wVectorT();
00074     template <bool OtherShared>
00075     wVectorT( const wVectorT<OtherShared>& );
00077     wVectorT( const wVectorT& );
00079     wVectorT( const real *ptr );
00081     wVectorT( real *ptr );
00083     wVectorT( real x, real y, real z, real w=1.0 );
00084 
00086     operator qglviewer::Vec() const;
00087 
00089     wVectorT<false> scale( real s ) const;
00093     wVectorT& normalize();
00094 
00096     real& operator[]( int i );
00098     const real& operator[]( int i ) const;
00099 
00101     wVectorT<false> operator-() const;
00103     const wVectorT& operator+() const;
00104 
00106     template <bool OtherShared>
00107     wVectorT<false> operator+( const wVectorT<OtherShared> &A ) const;
00109     template <bool OtherShared>
00110     wVectorT<false> operator-( const wVectorT<OtherShared> &A ) const;
00112     wVectorT& operator=( const wVectorT &A );
00114     template <bool OtherShared>
00115     wVectorT& operator=( const wVectorT<OtherShared> &A );
00117     template <bool OtherShared>
00118     wVectorT& operator+=( const wVectorT<OtherShared> &A );
00120     template <bool OtherShared>
00121     wVectorT& operator-=( const wVectorT<OtherShared> &A );
00122 
00124     template <bool OtherShared>
00125     bool operator==( const wVectorT<OtherShared> &A ) const;
00126 
00128     template <bool OtherShared>
00129     real operator%( const wVectorT<OtherShared> &A ) const;
00130 
00132     template <bool OtherShared>
00133     wVectorT<false> operator*( const wVectorT<OtherShared> &B ) const;
00134 
00136     template <bool OtherShared>
00137     wVectorT<false> compProduct( const wVectorT<OtherShared> &A ) const;
00138 
00140     real norm() const;
00141 
00143     template <bool SharedA, bool SharedB>
00144     static real distance( const wVectorT<SharedA> &A, const wVectorT<SharedB> &B );
00145 
00151     //template <bool OtherShared>
00152     wVectorT& rotateAround( wVectorT<false> axis, real theta );
00153 
00155     static wVectorT<false> X();
00157     static wVectorT<false> Y();
00159     static wVectorT<false> Z();
00160 
00161     real &x;
00162     real &y;
00163     real &z;
00164     real &w;
00165 };
00166 
00168 typedef wVectorT<false> wVector;
00169 
00170 template <bool Shared>
00171 inline wVectorT<false> wVectorT<Shared>::X() {
00172     return wVectorT<false>(1,0,0,0);
00173 }
00174 
00175 template <bool Shared>
00176 inline wVectorT<false> wVectorT<Shared>::Y() {
00177     return wVectorT<false>(0,1,0,0);
00178 }
00179 
00180 template <bool Shared>
00181 inline wVectorT<false> wVectorT<Shared>::Z() {
00182     return wVectorT<false>(0,0,1,0);
00183 }
00184 
00185 template <>
00186 inline wVectorT<false>::wVectorT() :
00187     x(InternalData<false>::data[0]),
00188     y(InternalData<false>::data[1]),
00189     z(InternalData<false>::data[2]),
00190     w(InternalData<false>::data[3])
00191 {
00192     x = 0.0;
00193     y = 0.0;
00194     z = 0.0;
00195     w = 1.0;
00196 }
00197 
00198 template <>
00199 template <bool OtherShared>
00200 inline wVectorT<false>::wVectorT( const wVectorT<OtherShared>& src ) :
00201     x(InternalData<false>::data[0]),
00202     y(InternalData<false>::data[1]),
00203     z(InternalData<false>::data[2]),
00204     w(InternalData<false>::data[3])
00205 {
00206     x = src.x;
00207     y = src.y;
00208     z = src.z;
00209     w = src.w;
00210 }
00211 
00212 template <>
00213 inline wVectorT<false>::wVectorT( const wVectorT<false>& src ) :
00214     x(InternalData<false>::data[0]),
00215     y(InternalData<false>::data[1]),
00216     z(InternalData<false>::data[2]),
00217     w(InternalData<false>::data[3])
00218 {
00219     x = src.x;
00220     y = src.y;
00221     z = src.z;
00222     w = src.w;
00223 }
00224 
00225 template <>
00226 inline wVectorT<false>::wVectorT(const real *ptr) :
00227     x(InternalData<false>::data[0]),
00228     y(InternalData<false>::data[1]),
00229     z(InternalData<false>::data[2]),
00230     w(InternalData<false>::data[3])
00231 {
00232     x = ptr[0];
00233     y = ptr[1];
00234     z = ptr[2];
00235     w = 1.0;
00236 }
00237 
00238 template <bool Shared>
00239 inline wVectorT<Shared>::wVectorT(real *ptr) :
00240     x(InternalData<Shared>::data[0]),
00241     y(InternalData<Shared>::data[1]),
00242     z(InternalData<Shared>::data[2]),
00243     w(InternalData<Shared>::data[3])
00244 {
00245     x = ptr[0];
00246     y = ptr[1];
00247     z = ptr[2];
00248     w = 1.0;
00249 }
00250 
00251 template <>
00252 inline wVectorT<true>::wVectorT(real *ptr) :
00253     x(ptr[0]),
00254     y(ptr[1]),
00255     z(ptr[2]),
00256     w(ptr[3])
00257 {
00258     w = 1.0;
00259 }
00260 
00261 template <>
00262 inline wVectorT<false>::wVectorT(real _x, real _y, real _z, real _w) :
00263     x(InternalData<false>::data[0]),
00264     y(InternalData<false>::data[1]),
00265     z(InternalData<false>::data[2]),
00266     w(InternalData<false>::data[3])
00267 {
00268     this->x = _x;
00269     this->y = _y;
00270     this->z = _z;
00271     this->w = _w;
00272 }
00273 
00274 template <bool Shared>
00275 inline wVectorT<Shared>::operator qglviewer::Vec() const {
00276     return qglviewer::Vec( x, y, z );
00277 }
00278 
00279 template <bool Shared>
00280 inline real& wVectorT<Shared>::operator[](int i) {
00281     return (&x)[i];
00282 }
00283 
00284 template <bool Shared>
00285 inline const real& wVectorT<Shared>::operator[](int i) const {
00286     return (&x)[i];
00287 }
00288 
00289 template <bool Shared>
00290 inline wVectorT<false> wVectorT<Shared>::scale(real scale) const {
00291     return wVectorT<false>(x*scale, y*scale, z*scale, w);
00292 }
00293 
00294 template <bool Shared>
00295 inline wVectorT<Shared>& wVectorT<Shared>::normalize() {
00296     wVectorT& self = (*this);
00297     real n = sqrt( self%self );
00298     self.x /= n;
00299     self.y /= n;
00300     self.z /= n;
00301     self.w = 0.0;
00302     return self;
00303 }
00304 
00305 template <bool Shared>
00306 inline wVectorT<false> wVectorT<Shared>::operator-() const {
00307     return wVectorT<false>( -x, -y, -z, w );
00308 }
00309 
00310 template <bool Shared>
00311 inline const wVectorT<Shared>& wVectorT<Shared>::operator+() const {
00312     return (*this);
00313 }
00314 
00315 template <bool Shared>
00316 template <bool OtherShared>
00317 inline wVectorT<false> wVectorT<Shared>::operator+(const wVectorT<OtherShared> &B) const {
00318     return wVectorT<false>(x+B.x, y+B.y, z+B.z, w);
00319 }
00320 
00321 template <bool Shared>
00322 template <bool OtherShared>
00323 inline wVectorT<false> wVectorT<Shared>::operator-(const wVectorT<OtherShared> &A) const {
00324     return wVectorT<false>(x-A.x, y-A.y, z-A.z, w);
00325 }
00326 
00327 template <bool Shared>
00328 inline wVectorT<Shared>& wVectorT<Shared>::operator=( const wVectorT &A )
00329 {
00330     x = A.x;
00331     y = A.y;
00332     z = A.z;
00333     w = A.w;
00334     return *this;
00335 }
00336 
00337 template <bool Shared>
00338 template <bool OtherShared>
00339 inline wVectorT<Shared>& wVectorT<Shared>::operator=(const wVectorT<OtherShared> &A) {
00340     x = A.x;
00341     y = A.y;
00342     z = A.z;
00343     w = A.w;
00344     return *this;
00345 }
00346 
00347 template <bool Shared>
00348 template <bool OtherShared>
00349 inline wVectorT<Shared>& wVectorT<Shared>::operator+=(const wVectorT<OtherShared> &A) {
00350     x += A.x;
00351     y += A.y;
00352     z += A.z;
00353     w = 1.0;
00354     return *this;
00355 }
00356 
00357 template <bool Shared>
00358 template <bool OtherShared>
00359 inline wVectorT<Shared>& wVectorT<Shared>::operator-=(const wVectorT<OtherShared> &A) {
00360     x -= A.x;
00361     y -= A.y;
00362     z -= A.z;
00363     w = 1.0;
00364     return *this;
00365 }
00366 
00367 template <bool Shared>
00368 template <bool OtherShared>
00369 inline bool wVectorT<Shared>::operator==( const wVectorT<OtherShared> &A ) const {
00370     return ( x==A.x && y==A.y && z==A.z );
00371 }
00372 
00373 template <bool Shared>
00374 template <bool OtherShared>
00375 inline real wVectorT<Shared>::operator%(const wVectorT<OtherShared> &A) const {
00376     return x*A.x + y*A.y + z*A.z;
00377 }
00378 
00379 template <bool Shared>
00380 template <bool OtherShared>
00381 inline wVectorT<false> wVectorT<Shared>::operator*(const wVectorT<OtherShared> &B) const {
00382     return wVectorT<false>(
00383             y*B.z - z*B.y,
00384             z*B.x - x*B.z,
00385             x*B.y - y*B.x,
00386             w);
00387 }
00388 
00389 template <bool Shared>
00390 template <bool OtherShared>
00391 inline wVectorT<false> wVectorT<Shared>::compProduct(const wVectorT<OtherShared> &A) const {
00392     return wVectorT<false>(x*A.x, y*A.y, z*A.z, A.w);
00393 }
00394 
00395 template <bool Shared>
00396 inline real wVectorT<Shared>::norm() const {
00397     return sqrt( x*x + y*y + z*z );
00398 }
00399 
00400 template <bool Shared>
00401 template <bool SharedA, bool SharedB>
00402 inline real wVectorT<Shared>::distance( const wVectorT<SharedA> &A, const wVectorT<SharedB> &B ) {
00403     return sqrt( (A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y) + (A.z-B.z)*(A.z-B.z) );
00404 }
00405 
00406 template <bool Shared>
00407 //template <bool OtherShared>
00408 inline wVectorT<Shared>& wVectorT<Shared>::rotateAround( wVectorT<false> axis, real theta ) {
00409     wVector q(0,0,0);
00410     double costheta, sintheta;
00411     axis.normalize();
00412     costheta = cos(theta);
00413     sintheta = sin(theta);
00414     q.x += (costheta + (1 - costheta) * axis.x * axis.x) * x;
00415     q.x += ((1 - costheta) * axis.x * axis.y - axis.z * sintheta) * y;
00416     q.x += ((1 - costheta) * axis.x * axis.z + axis.y * sintheta) * z;
00417 
00418     q.y += ((1 - costheta) * axis.x * axis.y + axis.z * sintheta) * x;
00419     q.y += (costheta + (1 - costheta) * axis.y * axis.y) * y;
00420     q.y += ((1 - costheta) * axis.y * axis.z - axis.x * sintheta) * z;
00421 
00422     q.z += ((1 - costheta) * axis.x * axis.z - axis.y * sintheta) * x;
00423     q.z += ((1 - costheta) * axis.y * axis.z + axis.x * sintheta) * y;
00424     q.z += (costheta + (1 - costheta) * axis.z * axis.z) * z;
00425     x = q.x;
00426     y = q.y;
00427     z = q.z;
00428     return (*this);
00429 }
00430 } // end namespace farsa
00431 
00432 #endif