View Issue Details
ID  Project  Category  View Status  Date Submitted  Last Update 

0027980  Open CASCADE  OCCT:Foundation Classes  public  20161018 22:45  20161123 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.0170157982991590e06, 0.47942631661652435} double[3] +[1] 0x000000000296d7c8 {2.7755575615628914e17, 0.99999999999775024, 2.1213182570534173e06} double[3] +[2] 0x000000000296d7e0 {0.47942631661760310, 1.8616310090147081e06, 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 

20161018 22:45  kgv  New Issue  
20161018 22:45  kgv  Assigned To  => abv 
20161018 22:46  kgv  Steps to Reproduce Updated  
20161018 23:17  kgv  Steps to Reproduce Updated  
20161018 23:18  kgv  Steps to Reproduce Updated  
20161020 18:58  kgv  Relationship added  related to 0027764 
20161122 10:44  kgv  Target Version  7.1.0 => 7.2.0 
20161122 12:26  abv  Status  new => assigned 
20161122 20:23  abv  Note Added: 0060696  
20161122 20:26  abv  Assigned To  abv => kgv 
20161122 20:26  abv  Status  assigned => feedback 
20161123 08:34  kgv  Note Added: 0060698  
20161123 08:34  kgv  Assigned To  kgv => bugmaster 
20161123 08:34  kgv  Resolution  open => no change required 
20161123 08:34  kgv  Target Version  7.2.0 => 7.1.0 
20161123 09:57  abv  Status  feedback => closed 
20161123 09:57  abv  Target Version  7.1.0 => 