axisAngle maintains angle between [0, π] so updated docs and tests accordingly
parent
8f2a00e4bd
commit
170d1526b7
|
|
@ -189,17 +189,7 @@ Vector Rot3::quaternion() const {
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
pair<Unit3, double> Rot3::axisAngle() {
|
pair<Unit3, double> Rot3::axisAngle() {
|
||||||
Vector3 omega = Rot3::Logmap(*this);
|
Vector3 omega = Rot3::Logmap(*this);
|
||||||
// Get the rotation angle.
|
return std::pair<Unit3, double>(Unit3(omega), omega.norm());
|
||||||
double theta = omega.norm();
|
|
||||||
|
|
||||||
// Check if angle `theta` belongs to (-pi, pi].
|
|
||||||
// If yes, rotate in opposite direction to maintain range.
|
|
||||||
// Since omega = theta * u, if all coefficients are negative,
|
|
||||||
// then theta is outside the expected range.
|
|
||||||
if ((omega.array() < 0).all()) {
|
|
||||||
theta = -theta;
|
|
||||||
}
|
|
||||||
return std::pair<Unit3, double>(Unit3(omega), theta);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
|
||||||
|
|
@ -465,6 +465,9 @@ namespace gtsam {
|
||||||
/**
|
/**
|
||||||
* Compute the Euler axis and angle (in radians) representation
|
* Compute the Euler axis and angle (in radians) representation
|
||||||
* of this rotation.
|
* of this rotation.
|
||||||
|
* The angle is in the range [0, π]. If the angle is not in the range,
|
||||||
|
* the axis is flipped around accordingly so that the returned angle is
|
||||||
|
* within the specified range.
|
||||||
* @return pair consisting of Unit3 axis and angle in radians
|
* @return pair consisting of Unit3 axis and angle in radians
|
||||||
*/
|
*/
|
||||||
std::pair<Unit3, double> axisAngle();
|
std::pair<Unit3, double> axisAngle();
|
||||||
|
|
|
||||||
|
|
@ -691,7 +691,8 @@ TEST(Rot3, axisAngle) {
|
||||||
/// Test for sign ambiguity
|
/// Test for sign ambiguity
|
||||||
theta = M_PI + M_PI/2; // 270 degrees
|
theta = M_PI + M_PI/2; // 270 degrees
|
||||||
Rot3 R2 = Rot3::AxisAngle(Unit3(0.1, 0.3, 0.4), theta);
|
Rot3 R2 = Rot3::AxisAngle(Unit3(0.1, 0.3, 0.4), theta);
|
||||||
EXPECT_DOUBLES_EQUAL(theta - 2*M_PI, R2.axisAngle().second, 1e-9);
|
EXPECT(assert_equal(Unit3(-0.1, -0.3, -0.4), R2.axisAngle().first, 1e-9));
|
||||||
|
EXPECT_DOUBLES_EQUAL(M_PI/2, R2.axisAngle().second, 1e-9);
|
||||||
|
|
||||||
theta = -(M_PI + M_PI/2); // 90 (or -270) degrees
|
theta = -(M_PI + M_PI/2); // 90 (or -270) degrees
|
||||||
R2 = Rot3::AxisAngle(Unit3(0.1, 0.3, 0.4), theta);
|
R2 = Rot3::AxisAngle(Unit3(0.1, 0.3, 0.4), theta);
|
||||||
|
|
@ -700,7 +701,8 @@ TEST(Rot3, axisAngle) {
|
||||||
/// Non-trivial angles
|
/// Non-trivial angles
|
||||||
theta = 195 * M_PI / 180; // 195 degrees
|
theta = 195 * M_PI / 180; // 195 degrees
|
||||||
Rot3 R3 = Rot3::AxisAngle(Unit3(0.1, 0.3, 0.4), theta);
|
Rot3 R3 = Rot3::AxisAngle(Unit3(0.1, 0.3, 0.4), theta);
|
||||||
EXPECT_DOUBLES_EQUAL(theta - 2*M_PI, R3.axisAngle().second, 1e-9);
|
EXPECT(assert_equal(Unit3(-0.1, -0.3, -0.4), R3.axisAngle().first, 1e-9));
|
||||||
|
EXPECT_DOUBLES_EQUAL(165*M_PI/180, R3.axisAngle().second, 1e-9);
|
||||||
|
|
||||||
theta = -195 * M_PI / 180; // 165 degrees
|
theta = -195 * M_PI / 180; // 165 degrees
|
||||||
R3 = Rot3::AxisAngle(Unit3(0.1, 0.3, 0.4), theta);
|
R3 = Rot3::AxisAngle(Unit3(0.1, 0.3, 0.4), theta);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue