View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0027980 | Open CASCADE | OCCT:Foundation Classes | public | 2016-10-18 22:45 | 2016-11-23 09:57 |
Reporter | kgv | Assigned To | bugmaster | ||
Priority | normal | Severity | minor | ||
Status | closed | Resolution | no change required | ||
Platform | Windows | OS | VC++ 2015 | ||
Product Version | 7.0.0 | ||||
Summary | 0027980: Foundation Classes - gp_Trsf computes incorrect transformation between two gp_Ax3 | ||||
Description | gp_Trsf class defines the following method://! Modifies this transformation so that it transforms the //! coordinates of any point, (x, y, z), relative to a source //! coordinate system into the coordinates (x', y', z') which //! are relative to a target coordinate system, but which //! represent the same point //! The transformation is from the coordinate //! system "FromSystem1" to the coordinate system "ToSystem2". void gp_Trsf::SetTransformation (const gp_Ax3& FromA1, const gp_Ax3& ToA2) The following test case computes transformation from reference system 1 to reference system 2 in three different ways and checks if applying result transformation on reference system 1 produces reference system 2. This check fails on specific reference systems. | ||||
Steps To Reproduce | // note that both ax3 defines the same // DY = gp_Dir (-0.408247948, 0.408246487, 0.816497684). gp_Ax3 aAx3From (gp::Origin(), gp_Dir(0.577350259, -0.577350259, 0.577350259), gp_Dir(0.707106769, 0.707106769, 0.000000000)); gp_Ax3 aAx3To (gp::Origin(), gp_Dir(0.167667553, -0.845678747, 0.506670535), gp_Dir(0.897341192, 0.343747377, 0.276796907)); // this code produces invalid transformation gp_Trsf aTrsf1; aTrsf1.SetTransformation (aCamEnd, aCamStart); // this code produces invalid transformation either gp_Trsf aTrsfStart, aTrsfEnd; aTrsfStart.SetTransformation (aCamStart, gp::XOY()); aTrsfEnd .SetTransformation (aCamEnd, gp::XOY()); gp_Trsf aTrsf2 = aTrsfStart.Inverted() * aTrsfEnd; // this code produces correct transformation gp_Quaternion aRotStart = aTrsfStart.GetRotation(); gp_Quaternion aRotEnd = aTrsfEnd .GetRotation(); gp_Quaternion aRotDelta = aRotEnd * aRotStart.Inverted(); gp_Trsf aTrsf3; aTrsf3.SetRotation (aRotDelta); // check results gp_Ax3 anAxTest1 = aAx3From.Transformed (aTrsf1); gp_Ax3 anAxTest2 = aAx3From.Transformed (aTrsf2); gp_Ax3 anAxTest3 = aAx3From.Transformed (aTrsf3); if (!anAxTest1.YDirection().IsEqual (aAx3To.YDirection(), Precision::Angular()) { theDI << "KO1"; } if (!anAxTest2.YDirection().IsEqual (aAx3To.YDirection(), Precision::Angular()) { theDI << "KO2"; } if (!anAxTest3.YDirection().IsEqual (aAx3To.YDirection(), Precision::Angular()) { theDI << "KO3"; } Dump: aTrsf1 and aTrsf2: shape gp_CompoundTrsf (7) gp_TrsfForm -matrix +[0] 0x000000000296d7b0 {0.87758213685926734, -1.0170157982991590e-06, -0.47942631661652435} double[3] +[1] 0x000000000296d7c8 {-2.7755575615628914e-17, 0.99999999999775024, -2.1213182570534173e-06} double[3] +[2] 0x000000000296d7e0 {0.47942631661760310, 1.8616310090147081e-06, 0.87758213685729292} double[3] aTrsf3: shape gp_Rotation (1) gp_TrsfForm -matrix +[0] 0x000000000296dd20 {0.89798546884484032, 0.37104661633947345, -0.23653013813579832} double[3] +[1] 0x000000000296dd38 {-0.41185269313539397, 0.89798488166961477, -0.15492098453705708} double[3] +[2] 0x000000000296dd50 {0.15491758099271757, 0.23653236733232877, 0.95919392319985486} double[3] + | ||||
Tags | No tags attached. | ||||
Test case number | |||||
|
Everything is correct. Consider that we have two axis placements, A1 and A2. Each defines corresponding coordinate system. We must also take into account that we are working in global coordinate system, let's call it A0. Method gp_Trsf::SetTransformation(A1,A2) computes transformation matrix that provides conversion of coordinates of arbitrary point in coordinates of A1 to coordinates of A2. It is composed of two transformations: Tp = T2^-1 * T1 where T1 and T2 define transformation of coordinates of arbitrary point in A1 and A2, respectively, to coordinates of the same point in A0, so that for any point p: p0 = T1 * p1 p0 = T2 * p2 i.e. p2 = T2^-1 * T1 * p1 If we want to move axes A1 to align them with A0, we need to apply inverse of T1. To recognize this, consider that this transformation, being expressed in coordinates of A0, should convert coordinates of the end of X axis of A1 to (1,0,0) which is exactly coordinates of this point in A1 coordinate system. Reverse move transformation (again expressed in coordinates A0) is naturally T1. The desired transformation aligning axes A1 to position of A2 can be expressed as two consequent transformation: align A1 to A0 (T1^-1), and then align A0 to A2 (T2): Tm = T2 * T1^-1 It is apparent that Tm is not inverse of Tp. The reason is that Tm is defined in coordinates of A0 while Tp is defined in coordinates of A2. Conversion of Tp to coordinates of A0 gives inverse of Tm: Tp0 = T2 * Tp * T2^-1 = T1 * T2^-1 = Tm^-1 Thus the code above should be corrected as follows (assuming aCamStart = aAx3From and aCamEnd = aAx3To) to produce correct transformation (in test 2): > gp_Trsf aTrsf2 = aTrsfEnd * aTrsfStart.Inverted(); |
|
OK, please close the issue. |
Date Modified | Username | Field | Change |
---|---|---|---|
2016-10-18 22:45 | kgv | New Issue | |
2016-10-18 22:45 | kgv | Assigned To | => abv |
2016-10-18 22:46 | kgv | Steps to Reproduce Updated | |
2016-10-18 23:17 | kgv | Steps to Reproduce Updated | |
2016-10-18 23:18 | kgv | Steps to Reproduce Updated | |
2016-10-20 18:58 | kgv | Relationship added | related to 0027764 |
2016-11-22 10:44 | kgv | Target Version | 7.1.0 => 7.2.0 |
2016-11-22 12:26 |
|
Status | new => assigned |
2016-11-22 20:23 |
|
Note Added: 0060696 | |
2016-11-22 20:26 |
|
Assigned To | abv => kgv |
2016-11-22 20:26 |
|
Status | assigned => feedback |
2016-11-23 08:34 | kgv | Note Added: 0060698 | |
2016-11-23 08:34 | kgv | Assigned To | kgv => bugmaster |
2016-11-23 08:34 | kgv | Resolution | open => no change required |
2016-11-23 08:34 | kgv | Target Version | 7.2.0 => 7.1.0 |
2016-11-23 09:57 |
|
Status | feedback => closed |
2016-11-23 09:57 |
|
Target Version | 7.1.0 => |