GeoDefinitions - Add function to extract the euler angles. Fix bugs in the intrinsic calculation of GeoRotation. Add corresponding unit test
Hi everybody,
first of all happy new year. My first project of the year is to take the AGDD-based Toroid plugin, load it and then dump the transient GeoModel tree in memory into a GeoModelXML like format. If that's done then we can say, wuuuhu cyaaa unmaintained AGDD code and in fact, any other piece of Geometry can be translated into the same format and we can do the same gestures to the depreciated code as to AGDD. But that's only neccessary, if it's as unmaintained. Anyhow, as a first step, I'd like to extract the six defining paramaters of a GeoTransform. The translation is a no-brainer. For the three Euler angles
a bit more work is needed. The GeoRotation implements kind of a concatenation of the rotation matrices, where I'm currently trying to figure out the respective order. If I interpret the constrcutor
GeoRotation::GeoRotation(double phi, double theta, double psi)
{
double sinPhi = std::sin( phi ), cosPhi = std::cos( phi );
double sinTheta = std::sin( theta ), cosTheta = std::cos( theta );
double sinPsi = std::sin( psi ), cosPsi = std::cos( psi );
this->operator()(0,0) = cosPsi * cosPhi - cosTheta * sinPhi * sinPsi;
this->operator()(0,1) = cosPsi * sinPhi + cosTheta * cosPhi * sinPsi;
this->operator()(0,2) = sinPsi * sinTheta;
this->operator()(1,0) = - sinPsi * cosPhi - cosTheta * sinPhi * cosPsi;
this->operator()(1,1) = - sinPsi * sinPhi + cosTheta * cosPhi * cosPsi;
this->operator()(1,2) = cosPsi * sinTheta;
this->operator()(2,0) = sinTheta * sinPhi;
this->operator()(2,1) = - sinTheta * cosPhi;
this->operator()(2,2) = cosTheta;
}
correctly, then
is the corresponding matrix equation. Next, let's see which of the three
okay,
Indeed, that's the rotation around the x-axis. Last but not least, the angle
That's another x-axis rotation. I was quite confused about this result, so I've written a quick unit test to repeat the exercise above
1: testEulerAngles() 19 The GeoTrf::GeoRotation around the x-axis with angle 315
1: 0.707107 -0.707107 0
1: 0.707107 0.707107 0
1: -0 -0 1
1: testEulerAngles() 27 The GeoTrf::GeoRotation around the y-axis with angle 315
1: 1 0 -0
1: -0 0.707107 -0.707107
1: -0 0.707107 0.707107
1: testEulerAngles() 35 The GeoTrf::GeoRotation around the z-axis with angle 315
1: 0.707107 -0.707107 -0
1: 0.707107 0.707107 0
1: 0 -0 1
Indeed, in 2 out of the three cases, the rotation matrix is actually the same. In athena, GeoRotations around the three 'axes' are used in the inner detector GeoModel. There're also three usages of the GeoRotation in GeoModelATLAS.
There's also another interesting bug that setting 2 angles to non-zero does not neccessarily construct a valid rotation matrix
Tagging: @boudreau, @tsulaia, @nstyles, @jchapman, @jcatmore, @mbandier, @sroe
Merge request reports
Activity
- Resolved by Johannes Junggeburth
added 2 commits
- e1f4bd17 - Fix compilation
- 32ac88cb - Merge branch 'GeoXMLDumpDev' of ssh://gitlab.cern.ch:7999/GeoModelDev/GeoModel into GeoXMLDumpDev
added 1 commit
- 0d0377c6 - Revise GeoRotation definition... Implement Euler angle extraction
- Resolved by Johannes Junggeburth
added 1 commit
- 36b2b389 - Add method to extract Euler angles from a rotation matrix
Thanks, @jojungge!
Just a quick first question. I noticed from the test output that the EulerAngles test takes a lot of time to complete, about 10 seconds:
Is that expected or foreseen? If not, why should it take so long? Does that come from the test alone or from the new extraction methods themselves?
Thanks!
--Ric.
On a previous topic: I don't know whether this is solved yet, but the way to extract a rotation from matrix you can use the following procedure:
- Get the axis of rotation. That's the eigenvector corresponding to eigenvalue=1.
- Get the angle of rotation from 1+2*cos(Theta) = trace (M).
Then you should be able to build a rotation from the axis and the angle. Does this help?