View Issue Details

IDProjectCategoryView StatusLast Update
0027980Open CASCADEOCCT:Foundation Classespublic2016-11-23 09:57
Reporterkgv Assigned Tobugmaster  
PrioritynormalSeverityminor 
Status closedResolutionno change required 
PlatformWindowsOSVC++ 2015 
Product Version7.0.0 
Summary0027980: Foundation Classes - gp_Trsf computes incorrect transformation between two gp_Ax3
Descriptiongp_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]
+
TagsNo tags attached.
Test case number

Relationships

related to 0027764 closedapn Visualization - add functionality for animation of 3D camera and interactive objects 

Activities

abv

2016-11-22 20:23

manager   ~0060696

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();

kgv

2016-11-23 08:34

developer   ~0060698

OK, please close the issue.

Issue History

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 abv Status new => assigned
2016-11-22 20:23 abv Note Added: 0060696
2016-11-22 20:26 abv Assigned To abv => kgv
2016-11-22 20:26 abv 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 abv Status feedback => closed
2016-11-23 09:57 abv Target Version 7.1.0 =>