1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0025574: gp_YawPitchRoll Euler Angle computation gives wrong results

Conversion of gp_Quaternion to and from intrinsic Tait-Bryan angles (including gp_YawPitchRoll) is fixed.

Before that fix the sequence of rotation axes was opposite to intended; e.g. gp_YawPitchRoll (equivalent to gp_Intrinsic_ZYX) actually was defining intrinsic rotations around X, then Y, then Z.
Now this is fixed, and rotations are made in correct order.

Comments to gp_EulerSequence enumeration are restored (lost due to CDL extraction).

Test bugs fclasses bug25574 is added to check correctness of Euler sequences, including cases from #25574 and #25946.
This commit is contained in:
akz
2015-10-13 10:30:52 +03:00
committed by bugmaster
parent 5fce160515
commit 4f5ad41656
6 changed files with 320 additions and 35 deletions

View File

@@ -17,35 +17,60 @@
#ifndef _gp_EulerSequence_HeaderFile
#define _gp_EulerSequence_HeaderFile
//! Enumerates all 24 possible variants of generalized
//! Euler angles, defining general 3d rotation by three
//! rotations around main axes of coordinate system,
//! in different possible orders.
//!
//! The name of the enumeration
//! corresponds to order of rotations, prefixed by type
//! of co-ordinate system used:
//! - Intrinsic: rotations are made around axes of rotating
//! co-ordinate system associated with the object
//! - Extrinsic: rotations are made around axes of fixed
//! (static) co-ordinate system
//!
//! Two specific values are provided for most frequently used
//! conventions: classic Euler angles (intrinsic ZXZ) and
//! yaw-pitch-roll (intrinsic ZYX).
enum gp_EulerSequence
{
gp_EulerAngles,
gp_YawPitchRoll,
gp_Extrinsic_XYZ,
gp_Extrinsic_XZY,
gp_Extrinsic_YZX,
gp_Extrinsic_YXZ,
gp_Extrinsic_ZXY,
gp_Extrinsic_ZYX,
gp_Intrinsic_XYZ,
gp_Intrinsic_XZY,
gp_Intrinsic_YZX,
gp_Intrinsic_YXZ,
gp_Intrinsic_ZXY,
gp_Intrinsic_ZYX,
gp_Extrinsic_XYX,
gp_Extrinsic_XZX,
gp_Extrinsic_YZY,
gp_Extrinsic_YXY,
gp_Extrinsic_ZYZ,
gp_Extrinsic_ZXZ,
gp_Intrinsic_XYX,
gp_Intrinsic_XZX,
gp_Intrinsic_YZY,
gp_Intrinsic_YXY,
gp_Intrinsic_ZXZ,
gp_Intrinsic_ZYZ
//! Classic Euler angles, alias to Intrinsic_ZXZ
gp_EulerAngles,
//! Yaw Pitch Roll (or nautical) angles, alias to Intrinsic_ZYX
gp_YawPitchRoll,
// Tait-Bryan angles (using three different axes)
gp_Extrinsic_XYZ,
gp_Extrinsic_XZY,
gp_Extrinsic_YZX,
gp_Extrinsic_YXZ,
gp_Extrinsic_ZXY,
gp_Extrinsic_ZYX,
gp_Intrinsic_XYZ,
gp_Intrinsic_XZY,
gp_Intrinsic_YZX,
gp_Intrinsic_YXZ,
gp_Intrinsic_ZXY,
gp_Intrinsic_ZYX,
// Proper Euler angles (using two different axes, first and third the same)
gp_Extrinsic_XYX,
gp_Extrinsic_XZX,
gp_Extrinsic_YZY,
gp_Extrinsic_YXY,
gp_Extrinsic_ZYZ,
gp_Extrinsic_ZXZ,
gp_Intrinsic_XYX,
gp_Intrinsic_XZX,
gp_Intrinsic_YZY,
gp_Intrinsic_YXY,
gp_Intrinsic_ZXZ,
gp_Intrinsic_ZYZ
};
#endif // _gp_EulerSequence_HeaderFile

View File

@@ -191,6 +191,8 @@ gp_Mat gp_Quaternion::GetMatrix () const
return aMat;
}
namespace { // anonymous namespace
//=======================================================================
//function : translateEulerSequence
//purpose :
@@ -237,12 +239,18 @@ gp_EulerSequence_Parameters translateEulerSequence (const gp_EulerSequence theSe
case gp_Extrinsic_ZXY: return Params (3, F, F, T);
case gp_Extrinsic_ZYX: return Params (3, T, F, T);
case gp_Intrinsic_XYZ: return Params (1, F, F, F);
case gp_Intrinsic_XZY: return Params (1, T, F, F);
case gp_Intrinsic_YZX: return Params (2, F, F, F);
case gp_Intrinsic_YXZ: return Params (2, T, F, F);
case gp_Intrinsic_ZXY: return Params (3, F, F, F);
case gp_Intrinsic_ZYX: return Params (3, T, F, F);
// Conversion of intrinsic angles is made by the same code as for extrinsic,
// using equivalence rule: intrinsic rotation is equivalent to extrinsic
// rotation by the same angles but with inverted order of elemental rotations.
// Swapping of angles (Alpha <-> Gamma) is done inside conversion procedure;
// sequence of axes is inverted by setting appropriate parameters here.
// Note that proper Euler angles (last block below) are symmetric for sequence of axes.
case gp_Intrinsic_XYZ: return Params (3, T, F, F);
case gp_Intrinsic_XZY: return Params (2, F, F, F);
case gp_Intrinsic_YZX: return Params (1, T, F, F);
case gp_Intrinsic_YXZ: return Params (3, F, F, F);
case gp_Intrinsic_ZXY: return Params (2, T, F, F);
case gp_Intrinsic_ZYX: return Params (1, F, F, F);
case gp_Extrinsic_XYX: return Params (1, F, T, T);
case gp_Extrinsic_XZX: return Params (1, T, T, T);
@@ -260,10 +268,12 @@ gp_EulerSequence_Parameters translateEulerSequence (const gp_EulerSequence theSe
default:
case gp_EulerAngles : return Params (3, F, T, F); // = Intrinsic_ZXZ
case gp_YawPitchRoll: return Params (3, T, F, F); // = Intrinsic_ZYX
case gp_YawPitchRoll: return Params (1, F, F, F); // = Intrinsic_ZYX
};
}
} // anonymous namespace
//=======================================================================
//function : SetEulerAngles
//purpose :