mirror of
https://gitlab.com/libeigen/eigen.git
synced 2024-12-21 07:19:46 +08:00
Transform::computeScalingRotation flush determinant to +/- 1.
In the previous code, in attempting to correct for a negative determinant, we end up multiplying and dividing by a number that is often very near, but not exactly +/-1. By flushing to +/-1, we can replace a division with a multiplication, and results are more numerically consistent.
This commit is contained in:
parent
587fd6ab70
commit
3daf92c7a5
@ -1097,16 +1097,17 @@ template<typename Scalar, int Dim, int Mode, int Options>
|
||||
template<typename RotationMatrixType, typename ScalingMatrixType>
|
||||
EIGEN_DEVICE_FUNC void Transform<Scalar,Dim,Mode,Options>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const
|
||||
{
|
||||
// TODO: investigate BDCSVD implementation.
|
||||
JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
|
||||
|
||||
Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1
|
||||
Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant() < Scalar(0) ? Scalar(-1) : Scalar(1); // so x has absolute value 1
|
||||
VectorType sv(svd.singularValues());
|
||||
sv.coeffRef(Dim-1) *= x;
|
||||
if(scaling) *scaling = svd.matrixV() * sv.asDiagonal() * svd.matrixV().adjoint();
|
||||
if(rotation)
|
||||
{
|
||||
LinearMatrixType m(svd.matrixU());
|
||||
m.col(Dim-1) /= x;
|
||||
m.col(Dim-1) *= x;
|
||||
*rotation = m * svd.matrixV().adjoint();
|
||||
}
|
||||
}
|
||||
@ -1126,16 +1127,17 @@ template<typename Scalar, int Dim, int Mode, int Options>
|
||||
template<typename ScalingMatrixType, typename RotationMatrixType>
|
||||
EIGEN_DEVICE_FUNC void Transform<Scalar,Dim,Mode,Options>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const
|
||||
{
|
||||
// TODO: investigate BDCSVD implementation.
|
||||
JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV);
|
||||
|
||||
Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant(); // so x has absolute value 1
|
||||
Scalar x = (svd.matrixU() * svd.matrixV().adjoint()).determinant() < Scalar(0) ? Scalar(-1) : Scalar(1); // so x has absolute value 1
|
||||
VectorType sv(svd.singularValues());
|
||||
sv.coeffRef(Dim-1) *= x;
|
||||
if(scaling) *scaling = svd.matrixU() * sv.asDiagonal() * svd.matrixU().adjoint();
|
||||
if(rotation)
|
||||
{
|
||||
LinearMatrixType m(svd.matrixU());
|
||||
m.col(Dim-1) /= x;
|
||||
m.col(Dim-1) *= x;
|
||||
*rotation = m * svd.matrixV().adjoint();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user