switch from eigensolver to SVD which seems to be more accurate with float

This commit is contained in:
Gael Guennebaud 2009-07-06 11:15:38 +02:00
parent 90f1e24579
commit 0cd158820c
2 changed files with 6 additions and 4 deletions

View File

@ -6,7 +6,7 @@
#include "src/Core/util/DisableMSVCWarnings.h" #include "src/Core/util/DisableMSVCWarnings.h"
#include "Array" #include "Array"
#include "QR" #include "SVD"
#include <limits> #include <limits>
#ifndef M_PI #ifndef M_PI

View File

@ -367,12 +367,14 @@ inline Quaternion<Scalar>& Quaternion<Scalar>::setFromTwoVectors(const MatrixBas
// x^T v1 = 0 // x^T v1 = 0
// under the constraint: // under the constraint:
// ||x|| = 1 // ||x|| = 1
// which yields an eigenvalue problem (or a SVD) // which yields a singular value problem
if (ei_isApprox(c,Scalar(-1))) if (ei_isApprox(c,Scalar(-1)))
{ {
c = std::max<Scalar>(c,-1); c = std::max<Scalar>(c,-1);
SelfAdjointEigenSolver<Matrix<Scalar,3,3> > eig(v0 * v0.transpose() + v1 * v1.transpose());
Vector3 axis = eig.eigenvectors().col(0); SVD<Matrix<Scalar,3,3> > svd(v0 * v0.transpose() + v1 * v1.transpose());
Vector3 axis = svd.matrixV().col(2);
Scalar w2 = (Scalar(1)+c)*Scalar(0.5); Scalar w2 = (Scalar(1)+c)*Scalar(0.5);
this->w() = ei_sqrt(w2); this->w() = ei_sqrt(w2);
this->vec() = axis * ei_sqrt(Scalar(1) - w2); this->vec() = axis * ei_sqrt(Scalar(1) - w2);