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:
@@ -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
|
||||
|
@@ -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 :
|
||||
|
Reference in New Issue
Block a user