TVector3::Rotate to arbitrary rotation using XYZVector

Hi,

I am trying to replace the deprecated TVector3 by Math/Vector3D, and XYZVector in particular. While with TVector3 I am able to do

TVector3 a; 
// set a to some meaningful vector
a.Rotate(someangle, someaxis);

I don’t really find the easiest way to do the same with the GenVectors. I tried

ROOT::Math::XYZVector a;
// set a to some meaningful vector
ROOT::Math::VectorUtil::Rotate(a, ROOT::Math::Rotation3D(ROOT::Math::AxisAngle(someaxis, someangle)));

but this does not work. I get the following error:

root/Math/GenVector/VectorUtil.h:348:29: error: no match for call to ‘(const ROOT::Math::Rotation3D) (int, int)’
  348 |             double x2 =  rot(0,0)*xX + rot(0,1)*yY + rot(0,2)*zZ;

and I understand the issue. But I don’t really see which generic rotation matrix I should use instead. The documentation of VectorUtil::Rotate just states that the template argument RotationMatrix has to have the corresponding operator (0, 0) etc. I find it strange that the Math::VectorUtil class Rotation3D does not provide this operator.

Which rotation matrix should I use instead? Or should I first create a Rotation3D to convert it to a different (rotation) matrix that has the required operator? Which does not sound like the way to go.

I have seen this question but I don’t think it’s applicable to my specific question.

Thanks a lot!


_ROOT Version: 6.24/06
_Platform: Ubuntu
_Compiler: g++ (GCC) 11.2.0


Hi,

I am deferring the answer to @moneta .

Best,
D

Thanks!

As an intermediate solution (i.e. mostly to have the project compile again), I hacked my way around that issue by creating a temporary TVector3 that I can rotate the same way as before and then convert it back to XYZVector. But of course that’s a very ugly and unsatisfying solution - and defies the purpose of replacing the deprecated TVector3 in the project completely.

I continue looking into the issue, but still didn’t find a better and more satisfying solution.

Hi, could you try copy-pasting this function into your code?

Please let us know if the result is the same as for TVector3.

Thanks @ferhue

testing with

void testRotation() {
    TVector3 at(17, -4, -23);
    XYZVector ag(17, -4, -23);
    double angle = 100;

    std::cout << "at: " << at.X() << ", " << at.Y() << ", " << at.Z() << std::endl;
    std::cout << "ag: " << ag.X() << ", " << ag.Y() << ", " << ag.Z() << std::endl;

    TVector3 axist(-23.4, 1.7, -0.3);
    XYZVector axisg(-23.4, 1.7, -0.3);

    std::cout << "axist: " << axist.X() << ", " << axist.Y() << ", " << axist.Z() << std::endl;
    std::cout << "axisg: " << axisg.X() << ", " << axisg.Y() << ", " << axisg.Z() << std::endl;

    at.Rotate(angle, axist);

    XYZVector rotated = Rotate(ag, angle, axisg);

    std::cout << "Rotated TVector: " << at.X() << ", " << at.Y() << ", " << at.Z() << std::endl;
    std::cout << "Rotated GenVector: " << rotated.X() << ", " << rotated.Y() << ", " << rotated.Z() << std::endl;
}

with several different values for the initial vector, the angle, and the axis I always observe the same result for both the rotated TVector3 as well as the rotated XYZVector (up to the 6th digit).

So yes, that function solves the issue. Thanks a lot!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.