matrix_3f.h
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2011, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  */
00034 
00037 #ifndef FCL_MATRIX_3F_H
00038 #define FCL_MATRIX_3F_H
00039 
00040 #include "fcl/math/vec_3f.h"
00041 
00042 namespace fcl
00043 {
00044 
00046 template<typename T>
00047 class Matrix3fX
00048 {
00049 public:
00050   typedef typename T::meta_type U;
00051   typedef typename T::vector_type S;
00052   T data;
00053   
00054   Matrix3fX() {}
00055   Matrix3fX(U xx, U xy, U xz,
00056             U yx, U yy, U yz,
00057             U zx, U zy, U zz) : data(xx, xy, xz, yx, yy, yz, zx, zy, zz)
00058   {}
00059 
00060   Matrix3fX(const Vec3fX<S>& v1, const Vec3fX<S>& v2, const Vec3fX<S>& v3)
00061     : data(v1.data, v2.data, v3.data) {}
00062   
00063   Matrix3fX(const Matrix3fX<T>& other) : data(other.data) {}
00064 
00065   Matrix3fX(const T& data_) : data(data_) {}
00066   
00067   inline Vec3fX<S> getColumn(size_t i) const
00068   {
00069     return Vec3fX<S>(data.getColumn(i));
00070   }
00071 
00072   inline Vec3fX<S> getRow(size_t i) const
00073   {
00074     return Vec3fX<S>(data.getRow(i));
00075   }
00076 
00077   inline U operator () (size_t i, size_t j) const
00078   {
00079     return data(i, j);
00080   }
00081 
00082   inline U& operator () (size_t i, size_t j)
00083   {
00084     return data(i, j);
00085   }
00086 
00087   inline Vec3fX<S> operator * (const Vec3fX<S>& v) const
00088   {
00089     return Vec3fX<S>(data * v.data);
00090   }
00091 
00092   inline Matrix3fX<T> operator * (const Matrix3fX<T>& m) const
00093   {
00094     return Matrix3fX<T>(data * m.data);
00095   }
00096 
00097   inline Matrix3fX<T> operator + (const Matrix3fX<T>& other) const
00098   {
00099     return Matrix3fX<T>(data + other.data);
00100   }
00101 
00102   inline Matrix3fX<T> operator - (const Matrix3fX<T>& other) const
00103   {
00104     return Matrix3fX<T>(data - other.data);
00105   }
00106 
00107   inline Matrix3fX<T> operator + (U c) const
00108   {
00109     return Matrix3fX<T>(data + c);
00110   }
00111 
00112   inline Matrix3fX<T> operator - (U c) const
00113   {
00114     return Matrix3fX<T>(data - c);
00115   }
00116 
00117   inline Matrix3fX<T> operator * (U c) const
00118   {
00119     return Matrix3fX<T>(data * c);
00120   }
00121 
00122   inline Matrix3fX<T> operator / (U c) const
00123   {
00124     return Matrix3fX<T>(data / c);
00125   }
00126 
00127   inline Matrix3fX<T>& operator *= (const Matrix3fX<T>& other)
00128   {
00129     data *= other.data;
00130     return *this;
00131   }
00132 
00133   inline Matrix3fX<T>& operator += (const Matrix3fX<T>& other)
00134   {
00135     data += other.data;
00136     return *this;
00137   }
00138 
00139   inline Matrix3fX<T>& operator -= (const Matrix3fX<T>& other)
00140   {
00141     data -= other.data;
00142     return *this;
00143   }
00144 
00145   inline Matrix3fX<T>& operator += (U c) 
00146   {
00147     data += c;
00148     return *this;
00149   }
00150 
00151   inline Matrix3fX<T>& operator -= (U c)
00152   {
00153     data -= c;
00154     return *this;
00155   }
00156 
00157   inline Matrix3fX<T>& operator *= (U c)
00158   {
00159     data *= c;
00160     return *this;
00161   }
00162 
00163   inline Matrix3fX<T>& operator /= (U c)
00164   {
00165     data /= c;
00166     return *this;
00167   }
00168 
00169   inline void setIdentity()
00170   {
00171     data.setIdentity();
00172   }
00173 
00174   inline void setZero()
00175   {
00176     data.setZero();
00177   }
00178 
00187   inline void setEulerZYX(FCL_REAL eulerX, FCL_REAL eulerY, FCL_REAL eulerZ)
00188   {
00189     FCL_REAL ci(cos(eulerX));
00190     FCL_REAL cj(cos(eulerY));
00191     FCL_REAL ch(cos(eulerZ));
00192     FCL_REAL si(sin(eulerX));
00193     FCL_REAL sj(sin(eulerY));
00194     FCL_REAL sh(sin(eulerZ));
00195     FCL_REAL cc = ci * ch;
00196     FCL_REAL cs = ci * sh;
00197     FCL_REAL sc = si * ch;
00198     FCL_REAL ss = si * sh;
00199 
00200     setValue(cj * ch, sj * sc - cs, sj * cc + ss,
00201              cj * sh, sj * ss + cc, sj * cs - sc, 
00202              -sj,     cj * si,      cj * ci);
00203 
00204   }
00205 
00210   void setEulerYPR(FCL_REAL yaw, FCL_REAL pitch, FCL_REAL roll)
00211   {
00212     setEulerZYX(roll, pitch, yaw);
00213   }
00214 
00215   inline U determinant() const
00216   {
00217     return data.determinant();
00218   }
00219 
00220   Matrix3fX<T>& transpose() 
00221   {
00222     data.transpose();
00223     return *this;
00224   }
00225 
00226   Matrix3fX<T>& inverse()
00227   {
00228     data.inverse();
00229     return *this;
00230   }
00231 
00232   Matrix3fX<T>& abs()
00233   {
00234     data.abs();
00235     return *this;
00236   }
00237 
00238   static const Matrix3fX<T>& getIdentity()
00239   {
00240     static const Matrix3fX<T> I((U)1, (U)0, (U)0,
00241                                 (U)0, (U)1, (U)0,
00242                                 (U)0, (U)0, (U)1);
00243     return I;
00244   }
00245 
00246   Matrix3fX<T> transposeTimes(const Matrix3fX<T>& other) const
00247   {
00248     return Matrix3fX<T>(data.transposeTimes(other.data));
00249   }
00250 
00251   Matrix3fX<T> timesTranspose(const Matrix3fX<T>& other) const
00252   {
00253     return Matrix3fX<T>(data.timesTranspose(other.data));
00254   }
00255 
00256   Vec3fX<S> transposeTimes(const Vec3fX<S>& v) const
00257   {
00258     return Vec3fX<S>(data.transposeTimes(v.data));
00259   }
00260 
00261   Matrix3fX<T> tensorTransform(const Matrix3fX<T>& m) const
00262   {
00263     Matrix3fX<T> res(*this);
00264     res *= m;
00265     return res.timesTranspose(*this);
00266   }
00267 
00268   inline U transposeDotX(const Vec3fX<S>& v) const
00269   {
00270     return data.transposeDot(0, v.data);
00271   }
00272 
00273   inline U transposeDotY(const Vec3fX<S>& v) const
00274   {
00275     return data.transposeDot(1, v.data);
00276   }
00277 
00278   inline U transposeDotZ(const Vec3fX<S>& v) const
00279   {
00280     return data.transposeDot(2, v.data);
00281   }
00282 
00283   inline U transposeDot(size_t i, const Vec3fX<S>& v) const
00284   {
00285     return data.transposeDot(i, v.data);
00286   }
00287 
00288   inline U dotX(const Vec3fX<S>& v) const
00289   {
00290     return data.dot(0, v.data);
00291   }
00292 
00293   inline U dotY(const Vec3fX<S>& v) const
00294   {
00295     return data.dot(1, v.data);
00296   }
00297 
00298   inline U dotZ(const Vec3fX<S>& v) const
00299   {
00300     return data.dot(2, v.data);
00301   }
00302 
00303   inline U dot(size_t i, const Vec3fX<S>& v) const
00304   {
00305     return data.dot(i, v.data);
00306   }
00307 
00308   inline void setValue(U xx, U xy, U xz,
00309                        U yx, U yy, U yz,
00310                        U zx, U zy, U zz)
00311   {
00312     data.setValue(xx, xy, xz, 
00313                   yx, yy, yz,
00314                   zx, zy, zz);
00315   }
00316 
00317   inline void setValue(U x)
00318   {
00319     data.setValue(x);
00320   }
00321 };
00322 
00323 template<typename T>
00324 void relativeTransform(const Matrix3fX<T>& R1, const Vec3fX<typename T::vector_type>& t1,
00325                        const Matrix3fX<T>& R2, const Vec3fX<typename T::vector_type>& t2,
00326                        Matrix3fX<T>& R, Vec3fX<typename T::vector_type>& t)
00327 {
00328   R = R1.transposeTimes(R2);
00329   t = R1.transposeTimes(t2 - t1);
00330 }
00331 
00333 template<typename T>
00334 void eigen(const Matrix3fX<T>& m, typename T::meta_type dout[3], Vec3fX<typename T::vector_type> vout[3])
00335 {
00336   Matrix3fX<T> R(m);
00337   int n = 3;
00338   int j, iq, ip, i;
00339   typename T::meta_type tresh, theta, tau, t, sm, s, h, g, c;
00340   int nrot;
00341   typename T::meta_type b[3];
00342   typename T::meta_type z[3];
00343   typename T::meta_type v[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
00344   typename T::meta_type d[3];
00345 
00346   for(ip = 0; ip < n; ++ip)
00347   {
00348     b[ip] = d[ip] = R(ip, ip);
00349     z[ip] = 0;
00350   }
00351 
00352   nrot = 0;
00353 
00354   for(i = 0; i < 50; ++i)
00355   {
00356     sm = 0;
00357     for(ip = 0; ip < n; ++ip)
00358       for(iq = ip + 1; iq < n; ++iq)
00359         sm += std::abs(R(ip, iq));
00360     if(sm == 0.0)
00361     {
00362       vout[0].setValue(v[0][0], v[0][1], v[0][2]);
00363       vout[1].setValue(v[1][0], v[1][1], v[1][2]);
00364       vout[2].setValue(v[2][0], v[2][1], v[2][2]);
00365       dout[0] = d[0]; dout[1] = d[1]; dout[2] = d[2];
00366       return;
00367     }
00368 
00369     if(i < 3) tresh = 0.2 * sm / (n * n);
00370     else tresh = 0.0;
00371 
00372     for(ip = 0; ip < n; ++ip)
00373     {
00374       for(iq= ip + 1; iq < n; ++iq)
00375       {
00376         g = 100.0 * std::abs(R(ip, iq));
00377         if(i > 3 &&
00378            std::abs(d[ip]) + g == std::abs(d[ip]) &&
00379            std::abs(d[iq]) + g == std::abs(d[iq]))
00380           R(ip, iq) = 0.0;
00381         else if(std::abs(R(ip, iq)) > tresh)
00382         {
00383           h = d[iq] - d[ip];
00384           if(std::abs(h) + g == std::abs(h)) t = (R(ip, iq)) / h;
00385           else
00386           {
00387             theta = 0.5 * h / (R(ip, iq));
00388             t = 1.0 /(std::abs(theta) + std::sqrt(1.0 + theta * theta));
00389             if(theta < 0.0) t = -t;
00390           }
00391           c = 1.0 / std::sqrt(1 + t * t);
00392           s = t * c;
00393           tau = s / (1.0 + c);
00394           h = t * R(ip, iq);
00395           z[ip] -= h;
00396           z[iq] += h;
00397           d[ip] -= h;
00398           d[iq] += h;
00399           R(ip, iq) = 0.0;
00400           for(j = 0; j < ip; ++j) { g = R(j, ip); h = R(j, iq); R(j, ip) = g - s * (h + g * tau); R(j, iq) = h + s * (g - h * tau); }
00401           for(j = ip + 1; j < iq; ++j) { g = R(ip, j); h = R(j, iq); R(ip, j) = g - s * (h + g * tau); R(j, iq) = h + s * (g - h * tau); }
00402           for(j = iq + 1; j < n; ++j) { g = R(ip, j); h = R(iq, j); R(ip, j) = g - s * (h + g * tau); R(iq, j) = h + s * (g - h * tau); }
00403           for(j = 0; j < n; ++j) { g = v[j][ip]; h = v[j][iq]; v[j][ip] = g - s * (h + g * tau); v[j][iq] = h + s * (g - h * tau); }
00404           nrot++;
00405         }
00406       }
00407     }
00408     for(ip = 0; ip < n; ++ip)
00409     {
00410       b[ip] += z[ip];
00411       d[ip] = b[ip];
00412       z[ip] = 0.0;
00413     }
00414   }
00415 
00416   std::cerr << "eigen: too many iterations in Jacobi transform." << std::endl;
00417 
00418   return;
00419 }
00420 
00421 template<typename T>
00422 Matrix3fX<T> abs(const Matrix3fX<T>& R) 
00423 {
00424   return Matrix3fX<T>(abs(R.data));
00425 }
00426 
00427 template<typename T>
00428 Matrix3fX<T> transpose(const Matrix3fX<T>& R)
00429 {
00430   return Matrix3fX<T>(transpose(R.data));
00431 }
00432 
00433 template<typename T>
00434 Matrix3fX<T> inverse(const Matrix3fX<T>& R)
00435 {
00436   return Matrix3fX<T>(inverse(R.data));
00437 }
00438 
00439 template<typename T>
00440 typename T::meta_type quadraticForm(const Matrix3fX<T>& R, const Vec3fX<typename T::vector_type>& v)
00441 {
00442   return v.dot(R * v);
00443 }
00444 
00445 
00446 #if FCL_HAVE_SSE
00447 typedef Matrix3fX<details::sse_meta_f12> Matrix3f;
00448 #else
00449 typedef Matrix3fX<details::Matrix3Data<FCL_REAL> > Matrix3f;
00450 #endif
00451 
00452 static inline std::ostream& operator << (std::ostream& o, const Matrix3f& m)
00453 {
00454   o << "[(" << m(0, 0) << " " << m(0, 1) << " " << m(0, 2) << ")("
00455     << m(1, 0) << " " << m(1, 1) << " " << m(1, 2) << ")(" 
00456     << m(2, 0) << " " << m(2, 1) << " " << m(2, 2) << ")]";
00457   return o;
00458 }
00459 
00460 
00461 
00463 class Variance3f
00464 {
00465 public:
00467   Matrix3f Sigma;
00468 
00470   Matrix3f::U sigma[3];
00471 
00473   Vec3f axis[3];
00474 
00475   Variance3f() {}
00476 
00477   Variance3f(const Matrix3f& S) : Sigma(S)
00478   {
00479     init();
00480   }
00481 
00483   void init() 
00484   {
00485     eigen(Sigma, sigma, axis);
00486   }
00487 
00489   Variance3f& sqrt()
00490   {
00491     for(std::size_t i = 0; i < 3; ++i)
00492     {
00493       if(sigma[i] < 0) sigma[i] = 0;
00494       sigma[i] = std::sqrt(sigma[i]);
00495     }
00496 
00497 
00498     Sigma.setZero();
00499     for(std::size_t i = 0; i < 3; ++i)
00500     {
00501       for(std::size_t j = 0; j < 3; ++j)
00502       {
00503         Sigma(i, j) += sigma[0] * axis[0][i] * axis[0][j];
00504         Sigma(i, j) += sigma[1] * axis[1][i] * axis[1][j];
00505         Sigma(i, j) += sigma[2] * axis[2][i] * axis[2][j];
00506       }
00507     }
00508 
00509     return *this;
00510   }
00511 };
00512 
00513 }
00514 
00515 
00516 
00517 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


fcl
Author(s): Jia Pan
autogenerated on Tue Jan 15 2013 16:05:30