77 # pragma GCC system_header
78 #elif defined __SUNPRO_CC
80 #elif defined _MSC_VER
81 # pragma warning(push, 1)
84 #include <Eigen/StdVector>
86 #include <Eigen/Eigenvalues>
87 #include <Eigen/Geometry>
90 #include <Eigen/Dense>
91 #include <Eigen/Eigenvalues>
95 template <
typename Scalar>
inline Scalar
100 template<>
inline double
103 return (::
sqrt (val));
106 template<>
inline float
109 return (::sqrtf (val));
112 template<>
inline long double
115 return (::sqrtl (val));
123 template<
typename Scalar,
typename Roots>
inline void
126 roots (0) = Scalar (0);
127 Scalar d = Scalar (b * b - 4.0 * c);
131 Scalar sd =
sqrt (d);
133 roots (2) = 0.5f * (b + sd);
134 roots (1) = 0.5f * (b - sd);
141 template<
typename Matrix,
typename Roots>
inline void
144 typedef typename Matrix::Scalar Scalar;
149 Scalar c0 = m (0, 0) * m (1, 1) * m (2, 2)
150 + Scalar (2) * m (0, 1) * m (0, 2) * m (1, 2)
151 - m (0, 0) * m (1, 2) * m (1, 2)
152 - m (1, 1) * m (0, 2) * m (0, 2)
153 - m (2, 2) * m (0, 1) * m (0, 1);
154 Scalar c1 = m (0, 0) * m (1, 1) -
155 m (0, 1) * m (0, 1) +
156 m (0, 0) * m (2, 2) -
157 m (0, 2) * m (0, 2) +
158 m (1, 1) * m (2, 2) -
160 Scalar c2 = m (0, 0) + m (1, 1) + m (2, 2);
163 if (fabs (c0) < Eigen::NumTraits<Scalar>::epsilon ())
167 const Scalar s_inv3 = Scalar (1.0 / 3.0);
171 Scalar c2_over_3 = c2*s_inv3;
172 Scalar a_over_3 = (c1 - c2 * c2_over_3) * s_inv3;
173 if (a_over_3 > Scalar (0))
174 a_over_3 = Scalar (0);
176 Scalar half_b = Scalar (0.5) * (c0 + c2_over_3 * (Scalar (2) * c2_over_3 * c2_over_3 - c1));
178 Scalar q = half_b * half_b + a_over_3 * a_over_3*a_over_3;
185 Scalar cos_theta = Eigen::internal::cos (theta);
186 Scalar sin_theta = Eigen::internal::sin (theta);
187 roots (0) = c2_over_3 + Scalar (2) * rho * cos_theta;
188 roots (1) = c2_over_3 - rho * (cos_theta + s_sqrt3 * sin_theta);
189 roots (2) = c2_over_3 - rho * (cos_theta - s_sqrt3 * sin_theta);
192 if (roots (0) >= roots (1))
193 std::swap (roots (0), roots (1));
194 if (roots (1) >= roots (2))
196 std::swap (roots (1), roots (2));
197 if (roots (0) >= roots (1))
198 std::swap (roots (0), roots (1));
212 template <
typename Matrix,
typename Vector>
inline void
213 eigen22 (
const Matrix& mat,
typename Matrix::Scalar& eigenvalue, Vector& eigenvector)
217 if (fabs(mat.coeff (1)) <= std::numeric_limits<typename Matrix::Scalar>::min ())
219 if (mat.coeff (0) < mat.coeff (2))
221 eigenvalue = mat.coeff (0);
222 eigenvector [0] = 1.0;
223 eigenvector [1] = 0.0;
227 eigenvalue = mat.coeff (2);
228 eigenvector [0] = 0.0;
229 eigenvector [1] = 1.0;
235 typename Matrix::Scalar trace =
static_cast<typename Matrix::Scalar
> (0.5) * (mat.coeff (0) + mat.coeff (3));
236 typename Matrix::Scalar determinant = mat.coeff (0) * mat.coeff (3) - mat.coeff (1) * mat.coeff (1);
238 typename Matrix::Scalar temp = trace * trace - determinant;
243 eigenvalue = trace -
sqrt (temp);
245 eigenvector [0] = - mat.coeff (1);
246 eigenvector [1] = mat.coeff (0) - eigenvalue;
247 eigenvector.normalize ();
256 template <
typename Matrix,
typename Vector>
inline void
257 eigen22 (
const Matrix& mat, Matrix& eigenvectors, Vector& eigenvalues)
261 if (fabs(mat.coeff (1)) <= std::numeric_limits<typename Matrix::Scalar>::min ())
263 if (mat.coeff (0) < mat.coeff (3))
265 eigenvalues.coeffRef (0) = mat.coeff (0);
266 eigenvalues.coeffRef (1) = mat.coeff (3);
267 eigenvectors.coeffRef (0) = 1.0;
268 eigenvectors.coeffRef (1) = 0.0;
269 eigenvectors.coeffRef (2) = 0.0;
270 eigenvectors.coeffRef (3) = 1.0;
274 eigenvalues.coeffRef (0) = mat.coeff (3);
275 eigenvalues.coeffRef (1) = mat.coeff (0);
276 eigenvectors.coeffRef (0) = 0.0;
277 eigenvectors.coeffRef (1) = 1.0;
278 eigenvectors.coeffRef (2) = 1.0;
279 eigenvectors.coeffRef (3) = 0.0;
285 typename Matrix::Scalar trace =
static_cast<typename Matrix::Scalar
> (0.5) * (mat.coeff (0) + mat.coeff (3));
286 typename Matrix::Scalar determinant = mat.coeff (0) * mat.coeff (3) - mat.coeff (1) * mat.coeff (1);
288 typename Matrix::Scalar temp = trace * trace - determinant;
295 eigenvalues.coeffRef (0) = trace - temp;
296 eigenvalues.coeffRef (1) = trace + temp;
299 eigenvectors.coeffRef (0) = - mat.coeff (1);
300 eigenvectors.coeffRef (2) = mat.coeff (0) - eigenvalues.coeff (0);
301 typename Matrix::Scalar norm =
static_cast<typename Matrix::Scalar
> (1.0) /
302 static_cast<typename Matrix::Scalar
> (
sqrt (eigenvectors.coeffRef (0) * eigenvectors.coeffRef (0) + eigenvectors.coeffRef (2) * eigenvectors.coeffRef (2)));
303 eigenvectors.coeffRef (0) *= norm;
304 eigenvectors.coeffRef (2) *= norm;
305 eigenvectors.coeffRef (1) = eigenvectors.coeffRef (2);
306 eigenvectors.coeffRef (3) = -eigenvectors.coeffRef (0);
315 template<
typename Matrix,
typename Vector>
inline void
318 typedef typename Matrix::Scalar Scalar;
322 Scalar scale = mat.cwiseAbs ().maxCoeff ();
323 if (scale <= std::numeric_limits<Scalar>::min ())
324 scale = Scalar (1.0);
326 Matrix scaledMat = mat / scale;
328 scaledMat.diagonal ().array () -= eigenvalue / scale;
330 Vector vec1 = scaledMat.row (0).cross (scaledMat.row (1));
331 Vector vec2 = scaledMat.row (0).cross (scaledMat.row (2));
332 Vector vec3 = scaledMat.row (1).cross (scaledMat.row (2));
334 Scalar len1 = vec1.squaredNorm ();
335 Scalar len2 = vec2.squaredNorm ();
336 Scalar len3 = vec3.squaredNorm ();
338 if (len1 >= len2 && len1 >= len3)
340 else if (len2 >= len1 && len2 >= len3)
353 template<
typename Matrix,
typename Vector>
inline void
354 eigen33 (
const Matrix& mat,
typename Matrix::Scalar& eigenvalue, Vector& eigenvector)
356 typedef typename Matrix::Scalar Scalar;
360 Scalar scale = mat.cwiseAbs ().maxCoeff ();
361 if (scale <= std::numeric_limits<Scalar>::min ())
362 scale = Scalar (1.0);
364 Matrix scaledMat = mat / scale;
369 eigenvalue = eigenvalues (0) * scale;
371 scaledMat.diagonal ().array () -= eigenvalues (0);
373 Vector vec1 = scaledMat.row (0).cross (scaledMat.row (1));
374 Vector vec2 = scaledMat.row (0).cross (scaledMat.row (2));
375 Vector vec3 = scaledMat.row (1).cross (scaledMat.row (2));
377 Scalar len1 = vec1.squaredNorm ();
378 Scalar len2 = vec2.squaredNorm ();
379 Scalar len3 = vec3.squaredNorm ();
381 if (len1 >= len2 && len1 >= len3)
383 else if (len2 >= len1 && len2 >= len3)
394 template<
typename Matrix,
typename Vector>
inline void
397 typedef typename Matrix::Scalar Scalar;
398 Scalar scale = mat.cwiseAbs ().maxCoeff ();
399 if (scale <= std::numeric_limits<Scalar>::min ())
400 scale = Scalar (1.0);
402 Matrix scaledMat = mat / scale;
413 template<
typename Matrix,
typename Vector>
inline void
414 eigen33 (
const Matrix& mat, Matrix& evecs, Vector& evals)
416 typedef typename Matrix::Scalar Scalar;
420 Scalar scale = mat.cwiseAbs ().maxCoeff ();
421 if (scale <= std::numeric_limits<Scalar>::min ())
422 scale = Scalar (1.0);
424 Matrix scaledMat = mat / scale;
429 if ((evals (2) - evals (0)) <= Eigen::NumTraits<Scalar>::epsilon ())
432 evecs.setIdentity ();
434 else if ((evals (1) - evals (0)) <= Eigen::NumTraits<Scalar>::epsilon () )
439 tmp.diagonal ().array () -= evals (2);
441 Vector vec1 = tmp.row (0).cross (tmp.row (1));
442 Vector vec2 = tmp.row (0).cross (tmp.row (2));
443 Vector vec3 = tmp.row (1).cross (tmp.row (2));
445 Scalar len1 = vec1.squaredNorm ();
446 Scalar len2 = vec2.squaredNorm ();
447 Scalar len3 = vec3.squaredNorm ();
449 if (len1 >= len2 && len1 >= len3)
451 else if (len2 >= len1 && len2 >= len3)
456 evecs.col (1) = evecs.col (2).unitOrthogonal ();
457 evecs.col (0) = evecs.col (1).cross (evecs.col (2));
459 else if ((evals (2) - evals (1)) <= Eigen::NumTraits<Scalar>::epsilon () )
464 tmp.diagonal ().array () -= evals (0);
466 Vector vec1 = tmp.row (0).cross (tmp.row (1));
467 Vector vec2 = tmp.row (0).cross (tmp.row (2));
468 Vector vec3 = tmp.row (1).cross (tmp.row (2));
470 Scalar len1 = vec1.squaredNorm ();
471 Scalar len2 = vec2.squaredNorm ();
472 Scalar len3 = vec3.squaredNorm ();
474 if (len1 >= len2 && len1 >= len3)
476 else if (len2 >= len1 && len2 >= len3)
481 evecs.col (1) = evecs.col (0).unitOrthogonal ();
482 evecs.col (2) = evecs.col (0).cross (evecs.col (1));
488 tmp.diagonal ().array () -= evals (2);
490 Vector vec1 = tmp.row (0).cross (tmp.row (1));
491 Vector vec2 = tmp.row (0).cross (tmp.row (2));
492 Vector vec3 = tmp.row (1).cross (tmp.row (2));
494 Scalar len1 = vec1.squaredNorm ();
495 Scalar len2 = vec2.squaredNorm ();
496 Scalar len3 = vec3.squaredNorm ();
498 Scalar *mmax =
new Scalar[3];
502 unsigned int min_el = 2;
503 unsigned int max_el = 2;
504 if (len1 >= len2 && len1 >= len3)
509 else if (len2 >= len1 && len2 >= len3)
521 tmp.diagonal ().array () -= evals (1);
523 vec1 = tmp.row (0).cross (tmp.row (1));
524 vec2 = tmp.row (0).cross (tmp.row (2));
525 vec3 = tmp.row (1).cross (tmp.row (2));
527 len1 = vec1.squaredNorm ();
528 len2 = vec2.squaredNorm ();
529 len3 = vec3.squaredNorm ();
530 if (len1 >= len2 && len1 >= len3)
534 min_el = len1 <= mmax[min_el] ? 1 : min_el;
535 max_el = len1 > mmax[max_el] ? 1 : max_el;
537 else if (len2 >= len1 && len2 >= len3)
541 min_el = len2 <= mmax[min_el] ? 1 : min_el;
542 max_el = len2 > mmax[max_el] ? 1 : max_el;
548 min_el = len3 <= mmax[min_el] ? 1 : min_el;
549 max_el = len3 > mmax[max_el] ? 1 : max_el;
553 tmp.diagonal ().array () -= evals (0);
555 vec1 = tmp.row (0).cross (tmp.row (1));
556 vec2 = tmp.row (0).cross (tmp.row (2));
557 vec3 = tmp.row (1).cross (tmp.row (2));
559 len1 = vec1.squaredNorm ();
560 len2 = vec2.squaredNorm ();
561 len3 = vec3.squaredNorm ();
562 if (len1 >= len2 && len1 >= len3)
566 min_el = len3 <= mmax[min_el] ? 0 : min_el;
567 max_el = len3 > mmax[max_el] ? 0 : max_el;
569 else if (len2 >= len1 && len2 >= len3)
573 min_el = len3 <= mmax[min_el] ? 0 : min_el;
574 max_el = len3 > mmax[max_el] ? 0 : max_el;
580 min_el = len3 <= mmax[min_el] ? 0 : min_el;
581 max_el = len3 > mmax[max_el] ? 0 : max_el;
584 unsigned mid_el = 3 - min_el - max_el;
585 evecs.col (min_el) = evecs.col ((min_el + 1) % 3).cross ( evecs.col ((min_el + 2) % 3) ).normalized ();
586 evecs.col (mid_el) = evecs.col ((mid_el + 1) % 3).cross ( evecs.col ((mid_el + 2) % 3) ).normalized ();
602 template<
typename Matrix>
inline typename Matrix::Scalar
605 typedef typename Matrix::Scalar Scalar;
606 Scalar det = matrix.coeff (0) * matrix.coeff (3) - matrix.coeff (1) * matrix.coeff (2) ;
611 inverse.coeffRef (0) = matrix.coeff (3);
612 inverse.coeffRef (1) = - matrix.coeff (1);
613 inverse.coeffRef (2) = - matrix.coeff (2);
614 inverse.coeffRef (3) = matrix.coeff (0);
627 template<
typename Matrix>
inline typename Matrix::Scalar
630 typedef typename Matrix::Scalar Scalar;
641 Scalar fd_ee = matrix.coeff (4) * matrix.coeff (8) - matrix.coeff (7) * matrix.coeff (5);
642 Scalar ce_bf = matrix.coeff (2) * matrix.coeff (5) - matrix.coeff (1) * matrix.coeff (8);
643 Scalar be_cd = matrix.coeff (1) * matrix.coeff (5) - matrix.coeff (2) * matrix.coeff (4);
645 Scalar det = matrix.coeff (0) * fd_ee + matrix.coeff (1) * ce_bf + matrix.coeff (2) * be_cd;
650 inverse.coeffRef (0) = fd_ee;
651 inverse.coeffRef (1) = inverse.coeffRef (3) = ce_bf;
652 inverse.coeffRef (2) = inverse.coeffRef (6) = be_cd;
653 inverse.coeffRef (4) = (matrix.coeff (0) * matrix.coeff (8) - matrix.coeff (2) * matrix.coeff (2));
654 inverse.coeffRef (5) = inverse.coeffRef (7) = (matrix.coeff (1) * matrix.coeff (2) - matrix.coeff (0) * matrix.coeff (5));
655 inverse.coeffRef (8) = (matrix.coeff (0) * matrix.coeff (4) - matrix.coeff (1) * matrix.coeff (1));
667 template<
typename Matrix>
inline typename Matrix::Scalar
670 typedef typename Matrix::Scalar Scalar;
677 Scalar ie_hf = matrix.coeff (8) * matrix.coeff (4) - matrix.coeff (7) * matrix.coeff (5);
678 Scalar hc_ib = matrix.coeff (7) * matrix.coeff (2) - matrix.coeff (8) * matrix.coeff (1);
679 Scalar fb_ec = matrix.coeff (5) * matrix.coeff (1) - matrix.coeff (4) * matrix.coeff (2);
680 Scalar det = matrix.coeff (0) * (ie_hf) + matrix.coeff (3) * (hc_ib) + matrix.coeff (6) * (fb_ec) ;
684 inverse.coeffRef (0) = ie_hf;
685 inverse.coeffRef (1) = hc_ib;
686 inverse.coeffRef (2) = fb_ec;
687 inverse.coeffRef (3) = matrix.coeff (6) * matrix.coeff (5) - matrix.coeff (8) * matrix.coeff (3);
688 inverse.coeffRef (4) = matrix.coeff (8) * matrix.coeff (0) - matrix.coeff (6) * matrix.coeff (2);
689 inverse.coeffRef (5) = matrix.coeff (3) * matrix.coeff (2) - matrix.coeff (5) * matrix.coeff (0);
690 inverse.coeffRef (6) = matrix.coeff (7) * matrix.coeff (3) - matrix.coeff (6) * matrix.coeff (4);
691 inverse.coeffRef (7) = matrix.coeff (6) * matrix.coeff (1) - matrix.coeff (7) * matrix.coeff (0);
692 inverse.coeffRef (8) = matrix.coeff (4) * matrix.coeff (0) - matrix.coeff (3) * matrix.coeff (1);
699 template<
typename Matrix>
inline typename Matrix::Scalar
703 return matrix.coeff (0) * (matrix.coeff (4) * matrix.coeff (8) - matrix.coeff (5) * matrix.coeff (7)) +
704 matrix.coeff (1) * (matrix.coeff (5) * matrix.coeff (6) - matrix.coeff (3) * matrix.coeff (8)) +
705 matrix.coeff (2) * (matrix.coeff (3) * matrix.coeff (7) - matrix.coeff (4) * matrix.coeff (6)) ;
717 Eigen::Affine3f& transformation);
726 inline Eigen::Affine3f
738 Eigen::Affine3f& transformation);
747 inline Eigen::Affine3f
759 Eigen::Affine3f& transformation);
768 inline Eigen::Affine3f
781 const Eigen::Vector3f& origin, Eigen::Affine3f& transformation);
791 getEulerAngles (
const Eigen::Affine3f& t,
float& roll,
float& pitch,
float& yaw);
805 float& roll,
float& pitch,
float& yaw);
818 getTransformation (
float x,
float y,
float z,
float roll,
float pitch,
float yaw, Eigen::Affine3f& t);
830 inline Eigen::Affine3f
831 getTransformation (
float x,
float y,
float z,
float roll,
float pitch,
float yaw);
838 template <
typename Derived>
void
839 saveBinary (
const Eigen::MatrixBase<Derived>& matrix, std::ostream& file);
846 template <
typename Derived>
void
847 loadBinary (Eigen::MatrixBase<Derived>
const& matrix, std::istream& file);
852 #if defined __SUNPRO_CC
854 #elif defined _MSC_VER
855 # pragma warning(pop)
858 #endif //#ifndef PCL_EIGEN_H_