00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #ifndef PCL_EIGEN_H_
00070 #define PCL_EIGEN_H_
00071
00072 #ifndef NOMINMAX
00073 #define NOMINMAX
00074 #endif
00075
00076 #if defined __GNUC__
00077 # pragma GCC system_header
00078 #elif defined __SUNPRO_CC
00079 # pragma disable_warn
00080 #elif defined _MSC_VER
00081 # pragma warning(push, 1)
00082 #endif
00083
00084 #include <Eigen/StdVector>
00085 #include <Eigen/Core>
00086 #include <Eigen/Eigenvalues>
00087 #include <Eigen/Geometry>
00088 #include <Eigen/SVD>
00089 #include <Eigen/LU>
00090 #include <Eigen/Dense>
00091 #include <Eigen/Eigenvalues>
00092
00093 namespace pcl
00094 {
00095 template <typename Scalar> inline Scalar
00096 sqrt (const Scalar &val)
00097 {
00098 }
00099
00100 template<> inline double
00101 sqrt<double> (const double &val)
00102 {
00103 return (::sqrt (val));
00104 }
00105
00106 template<> inline float
00107 sqrt<float> (const float &val)
00108 {
00109 return (::sqrtf (val));
00110 }
00111
00112 template<> inline long double
00113 sqrt<long double> (const long double &val)
00114 {
00115 return (::sqrtl (val));
00116 }
00117
00123 template<typename Scalar, typename Roots> inline void
00124 computeRoots2 (const Scalar& b, const Scalar& c, Roots& roots)
00125 {
00126 roots (0) = Scalar (0);
00127 Scalar d = Scalar (b * b - 4.0 * c);
00128 if (d < 0.0)
00129 d = 0.0;
00130
00131 Scalar sd = sqrt (d);
00132
00133 roots (2) = 0.5f * (b + sd);
00134 roots (1) = 0.5f * (b - sd);
00135 }
00136
00141 template<typename Matrix, typename Roots> inline void
00142 computeRoots (const Matrix& m, Roots& roots)
00143 {
00144 typedef typename Matrix::Scalar Scalar;
00145
00146
00147
00148
00149 Scalar c0 = m (0, 0) * m (1, 1) * m (2, 2)
00150 + Scalar (2) * m (0, 1) * m (0, 2) * m (1, 2)
00151 - m (0, 0) * m (1, 2) * m (1, 2)
00152 - m (1, 1) * m (0, 2) * m (0, 2)
00153 - m (2, 2) * m (0, 1) * m (0, 1);
00154 Scalar c1 = m (0, 0) * m (1, 1) -
00155 m (0, 1) * m (0, 1) +
00156 m (0, 0) * m (2, 2) -
00157 m (0, 2) * m (0, 2) +
00158 m (1, 1) * m (2, 2) -
00159 m (1, 2) * m (1, 2);
00160 Scalar c2 = m (0, 0) + m (1, 1) + m (2, 2);
00161
00162
00163 if (fabs (c0) < Eigen::NumTraits<Scalar>::epsilon ())
00164 computeRoots2 (c2, c1, roots);
00165 else
00166 {
00167 const Scalar s_inv3 = Scalar (1.0 / 3.0);
00168 const Scalar s_sqrt3 = Eigen::internal::sqrt (Scalar (3.0));
00169
00170
00171 Scalar c2_over_3 = c2*s_inv3;
00172 Scalar a_over_3 = (c1 - c2 * c2_over_3) * s_inv3;
00173 if (a_over_3 > Scalar (0))
00174 a_over_3 = Scalar (0);
00175
00176 Scalar half_b = Scalar (0.5) * (c0 + c2_over_3 * (Scalar (2) * c2_over_3 * c2_over_3 - c1));
00177
00178 Scalar q = half_b * half_b + a_over_3 * a_over_3*a_over_3;
00179 if (q > Scalar (0))
00180 q = Scalar (0);
00181
00182
00183 Scalar rho = Eigen::internal::sqrt (-a_over_3);
00184 Scalar theta = std::atan2 (Eigen::internal::sqrt (-q), half_b) * s_inv3;
00185 Scalar cos_theta = Eigen::internal::cos (theta);
00186 Scalar sin_theta = Eigen::internal::sin (theta);
00187 roots (0) = c2_over_3 + Scalar (2) * rho * cos_theta;
00188 roots (1) = c2_over_3 - rho * (cos_theta + s_sqrt3 * sin_theta);
00189 roots (2) = c2_over_3 - rho * (cos_theta - s_sqrt3 * sin_theta);
00190
00191
00192 if (roots (0) >= roots (1))
00193 std::swap (roots (0), roots (1));
00194 if (roots (1) >= roots (2))
00195 {
00196 std::swap (roots (1), roots (2));
00197 if (roots (0) >= roots (1))
00198 std::swap (roots (0), roots (1));
00199 }
00200
00201 if (roots (0) <= 0)
00202 computeRoots2 (c2, c1, roots);
00203 }
00204 }
00205
00212 template <typename Matrix, typename Vector> inline void
00213 eigen22 (const Matrix& mat, typename Matrix::Scalar& eigenvalue, Vector& eigenvector)
00214 {
00215
00216
00217 if (fabs(mat.coeff (1)) <= std::numeric_limits<typename Matrix::Scalar>::min ())
00218 {
00219 if (mat.coeff (0) < mat.coeff (2))
00220 {
00221 eigenvalue = mat.coeff (0);
00222 eigenvector [0] = 1.0;
00223 eigenvector [1] = 0.0;
00224 }
00225 else
00226 {
00227 eigenvalue = mat.coeff (2);
00228 eigenvector [0] = 0.0;
00229 eigenvector [1] = 1.0;
00230 }
00231 return;
00232 }
00233
00234
00235 typename Matrix::Scalar trace = static_cast<typename Matrix::Scalar> (0.5) * (mat.coeff (0) + mat.coeff (3));
00236 typename Matrix::Scalar determinant = mat.coeff (0) * mat.coeff (3) - mat.coeff (1) * mat.coeff (1);
00237
00238 typename Matrix::Scalar temp = trace * trace - determinant;
00239
00240 if (temp < 0)
00241 temp = 0;
00242
00243 eigenvalue = trace - sqrt (temp);
00244
00245 eigenvector [0] = - mat.coeff (1);
00246 eigenvector [1] = mat.coeff (0) - eigenvalue;
00247 eigenvector.normalize ();
00248 }
00249
00256 template <typename Matrix, typename Vector> inline void
00257 eigen22 (const Matrix& mat, Matrix& eigenvectors, Vector& eigenvalues)
00258 {
00259
00260
00261 if (fabs(mat.coeff (1)) <= std::numeric_limits<typename Matrix::Scalar>::min ())
00262 {
00263 if (mat.coeff (0) < mat.coeff (3))
00264 {
00265 eigenvalues.coeffRef (0) = mat.coeff (0);
00266 eigenvalues.coeffRef (1) = mat.coeff (3);
00267 eigenvectors.coeffRef (0) = 1.0;
00268 eigenvectors.coeffRef (1) = 0.0;
00269 eigenvectors.coeffRef (2) = 0.0;
00270 eigenvectors.coeffRef (3) = 1.0;
00271 }
00272 else
00273 {
00274 eigenvalues.coeffRef (0) = mat.coeff (3);
00275 eigenvalues.coeffRef (1) = mat.coeff (0);
00276 eigenvectors.coeffRef (0) = 0.0;
00277 eigenvectors.coeffRef (1) = 1.0;
00278 eigenvectors.coeffRef (2) = 1.0;
00279 eigenvectors.coeffRef (3) = 0.0;
00280 }
00281 return;
00282 }
00283
00284
00285 typename Matrix::Scalar trace = static_cast<typename Matrix::Scalar> (0.5) * (mat.coeff (0) + mat.coeff (3));
00286 typename Matrix::Scalar determinant = mat.coeff (0) * mat.coeff (3) - mat.coeff (1) * mat.coeff (1);
00287
00288 typename Matrix::Scalar temp = trace * trace - determinant;
00289
00290 if (temp < 0)
00291 temp = 0;
00292 else
00293 temp = sqrt (temp);
00294
00295 eigenvalues.coeffRef (0) = trace - temp;
00296 eigenvalues.coeffRef (1) = trace + temp;
00297
00298
00299 eigenvectors.coeffRef (0) = - mat.coeff (1);
00300 eigenvectors.coeffRef (2) = mat.coeff (0) - eigenvalues.coeff (0);
00301 typename Matrix::Scalar norm = static_cast<typename Matrix::Scalar> (1.0) /
00302 static_cast<typename Matrix::Scalar> (sqrt (eigenvectors.coeffRef (0) * eigenvectors.coeffRef (0) + eigenvectors.coeffRef (2) * eigenvectors.coeffRef (2)));
00303 eigenvectors.coeffRef (0) *= norm;
00304 eigenvectors.coeffRef (2) *= norm;
00305 eigenvectors.coeffRef (1) = eigenvectors.coeffRef (2);
00306 eigenvectors.coeffRef (3) = -eigenvectors.coeffRef (0);
00307 }
00308
00315 template<typename Matrix, typename Vector> inline void
00316 computeCorrespondingEigenVector (const Matrix& mat, const typename Matrix::Scalar& eigenvalue, Vector& eigenvector)
00317 {
00318 typedef typename Matrix::Scalar Scalar;
00319
00320
00321
00322 Scalar scale = mat.cwiseAbs ().maxCoeff ();
00323 if (scale <= std::numeric_limits<Scalar>::min ())
00324 scale = Scalar (1.0);
00325
00326 Matrix scaledMat = mat / scale;
00327
00328 scaledMat.diagonal ().array () -= eigenvalue / scale;
00329
00330 Vector vec1 = scaledMat.row (0).cross (scaledMat.row (1));
00331 Vector vec2 = scaledMat.row (0).cross (scaledMat.row (2));
00332 Vector vec3 = scaledMat.row (1).cross (scaledMat.row (2));
00333
00334 Scalar len1 = vec1.squaredNorm ();
00335 Scalar len2 = vec2.squaredNorm ();
00336 Scalar len3 = vec3.squaredNorm ();
00337
00338 if (len1 >= len2 && len1 >= len3)
00339 eigenvector = vec1 / Eigen::internal::sqrt (len1);
00340 else if (len2 >= len1 && len2 >= len3)
00341 eigenvector = vec2 / Eigen::internal::sqrt (len2);
00342 else
00343 eigenvector = vec3 / Eigen::internal::sqrt (len3);
00344 }
00345
00353 template<typename Matrix, typename Vector> inline void
00354 eigen33 (const Matrix& mat, typename Matrix::Scalar& eigenvalue, Vector& eigenvector)
00355 {
00356 typedef typename Matrix::Scalar Scalar;
00357
00358
00359
00360 Scalar scale = mat.cwiseAbs ().maxCoeff ();
00361 if (scale <= std::numeric_limits<Scalar>::min ())
00362 scale = Scalar (1.0);
00363
00364 Matrix scaledMat = mat / scale;
00365
00366 Vector eigenvalues;
00367 computeRoots (scaledMat, eigenvalues);
00368
00369 eigenvalue = eigenvalues (0) * scale;
00370
00371 scaledMat.diagonal ().array () -= eigenvalues (0);
00372
00373 Vector vec1 = scaledMat.row (0).cross (scaledMat.row (1));
00374 Vector vec2 = scaledMat.row (0).cross (scaledMat.row (2));
00375 Vector vec3 = scaledMat.row (1).cross (scaledMat.row (2));
00376
00377 Scalar len1 = vec1.squaredNorm ();
00378 Scalar len2 = vec2.squaredNorm ();
00379 Scalar len3 = vec3.squaredNorm ();
00380
00381 if (len1 >= len2 && len1 >= len3)
00382 eigenvector = vec1 / Eigen::internal::sqrt (len1);
00383 else if (len2 >= len1 && len2 >= len3)
00384 eigenvector = vec2 / Eigen::internal::sqrt (len2);
00385 else
00386 eigenvector = vec3 / Eigen::internal::sqrt (len3);
00387 }
00388
00394 template<typename Matrix, typename Vector> inline void
00395 eigen33 (const Matrix& mat, Vector& evals)
00396 {
00397 typedef typename Matrix::Scalar Scalar;
00398 Scalar scale = mat.cwiseAbs ().maxCoeff ();
00399 if (scale <= std::numeric_limits<Scalar>::min ())
00400 scale = Scalar (1.0);
00401
00402 Matrix scaledMat = mat / scale;
00403 computeRoots (scaledMat, evals);
00404 evals *= scale;
00405 }
00406
00413 template<typename Matrix, typename Vector> inline void
00414 eigen33 (const Matrix& mat, Matrix& evecs, Vector& evals)
00415 {
00416 typedef typename Matrix::Scalar Scalar;
00417
00418
00419
00420 Scalar scale = mat.cwiseAbs ().maxCoeff ();
00421 if (scale <= std::numeric_limits<Scalar>::min ())
00422 scale = Scalar (1.0);
00423
00424 Matrix scaledMat = mat / scale;
00425
00426
00427 computeRoots (scaledMat, evals);
00428
00429 if ((evals (2) - evals (0)) <= Eigen::NumTraits<Scalar>::epsilon ())
00430 {
00431
00432 evecs.setIdentity ();
00433 }
00434 else if ((evals (1) - evals (0)) <= Eigen::NumTraits<Scalar>::epsilon () )
00435 {
00436
00437 Matrix tmp;
00438 tmp = scaledMat;
00439 tmp.diagonal ().array () -= evals (2);
00440
00441 Vector vec1 = tmp.row (0).cross (tmp.row (1));
00442 Vector vec2 = tmp.row (0).cross (tmp.row (2));
00443 Vector vec3 = tmp.row (1).cross (tmp.row (2));
00444
00445 Scalar len1 = vec1.squaredNorm ();
00446 Scalar len2 = vec2.squaredNorm ();
00447 Scalar len3 = vec3.squaredNorm ();
00448
00449 if (len1 >= len2 && len1 >= len3)
00450 evecs.col (2) = vec1 / Eigen::internal::sqrt (len1);
00451 else if (len2 >= len1 && len2 >= len3)
00452 evecs.col (2) = vec2 / Eigen::internal::sqrt (len2);
00453 else
00454 evecs.col (2) = vec3 / Eigen::internal::sqrt (len3);
00455
00456 evecs.col (1) = evecs.col (2).unitOrthogonal ();
00457 evecs.col (0) = evecs.col (1).cross (evecs.col (2));
00458 }
00459 else if ((evals (2) - evals (1)) <= Eigen::NumTraits<Scalar>::epsilon () )
00460 {
00461
00462 Matrix tmp;
00463 tmp = scaledMat;
00464 tmp.diagonal ().array () -= evals (0);
00465
00466 Vector vec1 = tmp.row (0).cross (tmp.row (1));
00467 Vector vec2 = tmp.row (0).cross (tmp.row (2));
00468 Vector vec3 = tmp.row (1).cross (tmp.row (2));
00469
00470 Scalar len1 = vec1.squaredNorm ();
00471 Scalar len2 = vec2.squaredNorm ();
00472 Scalar len3 = vec3.squaredNorm ();
00473
00474 if (len1 >= len2 && len1 >= len3)
00475 evecs.col (0) = vec1 / Eigen::internal::sqrt (len1);
00476 else if (len2 >= len1 && len2 >= len3)
00477 evecs.col (0) = vec2 / Eigen::internal::sqrt (len2);
00478 else
00479 evecs.col (0) = vec3 / Eigen::internal::sqrt (len3);
00480
00481 evecs.col (1) = evecs.col (0).unitOrthogonal ();
00482 evecs.col (2) = evecs.col (0).cross (evecs.col (1));
00483 }
00484 else
00485 {
00486 Matrix tmp;
00487 tmp = scaledMat;
00488 tmp.diagonal ().array () -= evals (2);
00489
00490 Vector vec1 = tmp.row (0).cross (tmp.row (1));
00491 Vector vec2 = tmp.row (0).cross (tmp.row (2));
00492 Vector vec3 = tmp.row (1).cross (tmp.row (2));
00493
00494 Scalar len1 = vec1.squaredNorm ();
00495 Scalar len2 = vec2.squaredNorm ();
00496 Scalar len3 = vec3.squaredNorm ();
00497 #ifdef _WIN32
00498 Scalar *mmax = new Scalar[3];
00499 #else
00500 Scalar mmax[3];
00501 #endif
00502 unsigned int min_el = 2;
00503 unsigned int max_el = 2;
00504 if (len1 >= len2 && len1 >= len3)
00505 {
00506 mmax[2] = len1;
00507 evecs.col (2) = vec1 / Eigen::internal::sqrt (len1);
00508 }
00509 else if (len2 >= len1 && len2 >= len3)
00510 {
00511 mmax[2] = len2;
00512 evecs.col (2) = vec2 / Eigen::internal::sqrt (len2);
00513 }
00514 else
00515 {
00516 mmax[2] = len3;
00517 evecs.col (2) = vec3 / Eigen::internal::sqrt (len3);
00518 }
00519
00520 tmp = scaledMat;
00521 tmp.diagonal ().array () -= evals (1);
00522
00523 vec1 = tmp.row (0).cross (tmp.row (1));
00524 vec2 = tmp.row (0).cross (tmp.row (2));
00525 vec3 = tmp.row (1).cross (tmp.row (2));
00526
00527 len1 = vec1.squaredNorm ();
00528 len2 = vec2.squaredNorm ();
00529 len3 = vec3.squaredNorm ();
00530 if (len1 >= len2 && len1 >= len3)
00531 {
00532 mmax[1] = len1;
00533 evecs.col (1) = vec1 / Eigen::internal::sqrt (len1);
00534 min_el = len1 <= mmax[min_el] ? 1 : min_el;
00535 max_el = len1 > mmax[max_el] ? 1 : max_el;
00536 }
00537 else if (len2 >= len1 && len2 >= len3)
00538 {
00539 mmax[1] = len2;
00540 evecs.col (1) = vec2 / Eigen::internal::sqrt (len2);
00541 min_el = len2 <= mmax[min_el] ? 1 : min_el;
00542 max_el = len2 > mmax[max_el] ? 1 : max_el;
00543 }
00544 else
00545 {
00546 mmax[1] = len3;
00547 evecs.col (1) = vec3 / Eigen::internal::sqrt (len3);
00548 min_el = len3 <= mmax[min_el] ? 1 : min_el;
00549 max_el = len3 > mmax[max_el] ? 1 : max_el;
00550 }
00551
00552 tmp = scaledMat;
00553 tmp.diagonal ().array () -= evals (0);
00554
00555 vec1 = tmp.row (0).cross (tmp.row (1));
00556 vec2 = tmp.row (0).cross (tmp.row (2));
00557 vec3 = tmp.row (1).cross (tmp.row (2));
00558
00559 len1 = vec1.squaredNorm ();
00560 len2 = vec2.squaredNorm ();
00561 len3 = vec3.squaredNorm ();
00562 if (len1 >= len2 && len1 >= len3)
00563 {
00564 mmax[0] = len1;
00565 evecs.col (0) = vec1 / Eigen::internal::sqrt (len1);
00566 min_el = len3 <= mmax[min_el] ? 0 : min_el;
00567 max_el = len3 > mmax[max_el] ? 0 : max_el;
00568 }
00569 else if (len2 >= len1 && len2 >= len3)
00570 {
00571 mmax[0] = len2;
00572 evecs.col (0) = vec2 / Eigen::internal::sqrt (len2);
00573 min_el = len3 <= mmax[min_el] ? 0 : min_el;
00574 max_el = len3 > mmax[max_el] ? 0 : max_el;
00575 }
00576 else
00577 {
00578 mmax[0] = len3;
00579 evecs.col (0) = vec3 / Eigen::internal::sqrt (len3);
00580 min_el = len3 <= mmax[min_el] ? 0 : min_el;
00581 max_el = len3 > mmax[max_el] ? 0 : max_el;
00582 }
00583
00584 unsigned mid_el = 3 - min_el - max_el;
00585 evecs.col (min_el) = evecs.col ((min_el + 1) % 3).cross ( evecs.col ((min_el + 2) % 3) ).normalized ();
00586 evecs.col (mid_el) = evecs.col ((mid_el + 1) % 3).cross ( evecs.col ((mid_el + 2) % 3) ).normalized ();
00587 #ifdef _WIN32
00588 delete [] mmax;
00589 #endif
00590 }
00591
00592 evals *= scale;
00593 }
00594
00602 template<typename Matrix> inline typename Matrix::Scalar
00603 invert2x2 (const Matrix& matrix, Matrix& inverse)
00604 {
00605 typedef typename Matrix::Scalar Scalar;
00606 Scalar det = matrix.coeff (0) * matrix.coeff (3) - matrix.coeff (1) * matrix.coeff (2) ;
00607
00608 if (det != 0)
00609 {
00610
00611 inverse.coeffRef (0) = matrix.coeff (3);
00612 inverse.coeffRef (1) = - matrix.coeff (1);
00613 inverse.coeffRef (2) = - matrix.coeff (2);
00614 inverse.coeffRef (3) = matrix.coeff (0);
00615 inverse /= det;
00616 }
00617 return det;
00618 }
00619
00627 template<typename Matrix> inline typename Matrix::Scalar
00628 invert3x3SymMatrix (const Matrix& matrix, Matrix& inverse)
00629 {
00630 typedef typename Matrix::Scalar Scalar;
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641 Scalar fd_ee = matrix.coeff (4) * matrix.coeff (8) - matrix.coeff (7) * matrix.coeff (5);
00642 Scalar ce_bf = matrix.coeff (2) * matrix.coeff (5) - matrix.coeff (1) * matrix.coeff (8);
00643 Scalar be_cd = matrix.coeff (1) * matrix.coeff (5) - matrix.coeff (2) * matrix.coeff (4);
00644
00645 Scalar det = matrix.coeff (0) * fd_ee + matrix.coeff (1) * ce_bf + matrix.coeff (2) * be_cd;
00646
00647 if (det != 0)
00648 {
00649
00650 inverse.coeffRef (0) = fd_ee;
00651 inverse.coeffRef (1) = inverse.coeffRef (3) = ce_bf;
00652 inverse.coeffRef (2) = inverse.coeffRef (6) = be_cd;
00653 inverse.coeffRef (4) = (matrix.coeff (0) * matrix.coeff (8) - matrix.coeff (2) * matrix.coeff (2));
00654 inverse.coeffRef (5) = inverse.coeffRef (7) = (matrix.coeff (1) * matrix.coeff (2) - matrix.coeff (0) * matrix.coeff (5));
00655 inverse.coeffRef (8) = (matrix.coeff (0) * matrix.coeff (4) - matrix.coeff (1) * matrix.coeff (1));
00656 inverse /= det;
00657 }
00658 return det;
00659 }
00660
00667 template<typename Matrix> inline typename Matrix::Scalar
00668 invert3x3Matrix (const Matrix& matrix, Matrix& inverse)
00669 {
00670 typedef typename Matrix::Scalar Scalar;
00671
00672
00673
00674
00675
00676
00677 Scalar ie_hf = matrix.coeff (8) * matrix.coeff (4) - matrix.coeff (7) * matrix.coeff (5);
00678 Scalar hc_ib = matrix.coeff (7) * matrix.coeff (2) - matrix.coeff (8) * matrix.coeff (1);
00679 Scalar fb_ec = matrix.coeff (5) * matrix.coeff (1) - matrix.coeff (4) * matrix.coeff (2);
00680 Scalar det = matrix.coeff (0) * (ie_hf) + matrix.coeff (3) * (hc_ib) + matrix.coeff (6) * (fb_ec) ;
00681
00682 if (det != 0)
00683 {
00684 inverse.coeffRef (0) = ie_hf;
00685 inverse.coeffRef (1) = hc_ib;
00686 inverse.coeffRef (2) = fb_ec;
00687 inverse.coeffRef (3) = matrix.coeff (6) * matrix.coeff (5) - matrix.coeff (8) * matrix.coeff (3);
00688 inverse.coeffRef (4) = matrix.coeff (8) * matrix.coeff (0) - matrix.coeff (6) * matrix.coeff (2);
00689 inverse.coeffRef (5) = matrix.coeff (3) * matrix.coeff (2) - matrix.coeff (5) * matrix.coeff (0);
00690 inverse.coeffRef (6) = matrix.coeff (7) * matrix.coeff (3) - matrix.coeff (6) * matrix.coeff (4);
00691 inverse.coeffRef (7) = matrix.coeff (6) * matrix.coeff (1) - matrix.coeff (7) * matrix.coeff (0);
00692 inverse.coeffRef (8) = matrix.coeff (4) * matrix.coeff (0) - matrix.coeff (3) * matrix.coeff (1);
00693
00694 inverse /= det;
00695 }
00696 return det;
00697 }
00698
00699 template<typename Matrix> inline typename Matrix::Scalar
00700 determinant3x3Matrix (const Matrix& matrix)
00701 {
00702
00703 return matrix.coeff (0) * (matrix.coeff (4) * matrix.coeff (8) - matrix.coeff (5) * matrix.coeff (7)) +
00704 matrix.coeff (1) * (matrix.coeff (5) * matrix.coeff (6) - matrix.coeff (3) * matrix.coeff (8)) +
00705 matrix.coeff (2) * (matrix.coeff (3) * matrix.coeff (7) - matrix.coeff (4) * matrix.coeff (6)) ;
00706 }
00707
00715 inline void
00716 getTransFromUnitVectorsZY (const Eigen::Vector3f& z_axis, const Eigen::Vector3f& y_direction,
00717 Eigen::Affine3f& transformation);
00718
00726 inline Eigen::Affine3f
00727 getTransFromUnitVectorsZY (const Eigen::Vector3f& z_axis, const Eigen::Vector3f& y_direction);
00728
00736 inline void
00737 getTransFromUnitVectorsXY (const Eigen::Vector3f& x_axis, const Eigen::Vector3f& y_direction,
00738 Eigen::Affine3f& transformation);
00739
00747 inline Eigen::Affine3f
00748 getTransFromUnitVectorsXY (const Eigen::Vector3f& x_axis, const Eigen::Vector3f& y_direction);
00749
00757 inline void
00758 getTransformationFromTwoUnitVectors (const Eigen::Vector3f& y_direction, const Eigen::Vector3f& z_axis,
00759 Eigen::Affine3f& transformation);
00760
00768 inline Eigen::Affine3f
00769 getTransformationFromTwoUnitVectors (const Eigen::Vector3f& y_direction, const Eigen::Vector3f& z_axis);
00770
00779 inline void
00780 getTransformationFromTwoUnitVectorsAndOrigin (const Eigen::Vector3f& y_direction, const Eigen::Vector3f& z_axis,
00781 const Eigen::Vector3f& origin, Eigen::Affine3f& transformation);
00782
00790 inline void
00791 getEulerAngles (const Eigen::Affine3f& t, float& roll, float& pitch, float& yaw);
00792
00803 inline void
00804 getTranslationAndEulerAngles (const Eigen::Affine3f& t, float& x, float& y, float& z,
00805 float& roll, float& pitch, float& yaw);
00806
00817 inline void
00818 getTransformation (float x, float y, float z, float roll, float pitch, float yaw, Eigen::Affine3f& t);
00819
00830 inline Eigen::Affine3f
00831 getTransformation (float x, float y, float z, float roll, float pitch, float yaw);
00832
00838 template <typename Derived> void
00839 saveBinary (const Eigen::MatrixBase<Derived>& matrix, std::ostream& file);
00840
00846 template <typename Derived> void
00847 loadBinary (Eigen::MatrixBase<Derived> const& matrix, std::istream& file);
00848 }
00849
00850 #include <pcl/common/impl/eigen.hpp>
00851
00852 #if defined __SUNPRO_CC
00853 # pragma enable_warn
00854 #elif defined _MSC_VER
00855 # pragma warning(pop)
00856 #endif
00857
00858 #endif //#ifndef PCL_EIGEN_H_