FIX: auto-orient unstable due to numerical accuracy

jira: STUDIO-6464
Change-Id: I644bba2eea8cba6c73d2997c9399718b12eab9f2
(cherry picked from commit cccf57c75c3c348f918ededfbabb1eede5ac2ebd)
This commit is contained in:
Arthur 2024-04-10 12:20:38 +08:00 committed by Lane.Wei
parent d14f37b00f
commit ea838d3cc1
1 changed files with 6 additions and 30 deletions

View File

@ -343,36 +343,12 @@ Vec3d extract_euler_angles(const Transform3d& transform)
void rotation_from_two_vectors(Vec3d from, Vec3d to, Vec3d& rotation_axis, double& phi, Matrix3d* rotation_matrix) void rotation_from_two_vectors(Vec3d from, Vec3d to, Vec3d& rotation_axis, double& phi, Matrix3d* rotation_matrix)
{ {
double epsilon = 1e-5; const Matrix3d m = Eigen::Quaterniond().setFromTwoVectors(from, to).toRotationMatrix();
// note: a.isMuchSmallerThan(b,prec) compares a.abs().sum()<b*prec, so previously we set b=0 && prec=dummpy_prec() is wrong const Eigen::AngleAxisd aa(m);
if ((from + to).isMuchSmallerThan(1, epsilon)) rotation_axis = aa.axis();
{ phi = aa.angle();
rotation_axis << 1, 0, 0; if (rotation_matrix)
phi = M_PI; *rotation_matrix = m;
if (rotation_matrix)
*rotation_matrix = -Matrix3d::Identity();
}
else if ((from - to).isMuchSmallerThan(1, epsilon)) {
rotation_axis << 1, 0, 0;
phi = 0;
if (rotation_matrix)
*rotation_matrix = Matrix3d::Identity();
}
else {
rotation_axis = from.cross(to);
double s = rotation_axis.norm(); // sin(phi)
double c = from.dot(to); // cos(phi)
auto& v = rotation_axis;
Matrix3d kmat;
kmat << 0, -v[2], v[1],
v[2], 0, -v[0],
-v[1], v[0], 0;
rotation_axis.normalize();
phi = acos(std::min(from.dot(to), 1.0));
if (rotation_matrix)
*rotation_matrix = Matrix3d::Identity() + kmat + kmat * kmat * ((1 - c) / (s * s));
}
} }
Transform3d translation_transform(const Vec3d &translation) Transform3d translation_transform(const Vec3d &translation)