Skip to content
47 changes: 43 additions & 4 deletions math/genvector/inc/Math/GenVector/VectorUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,15 +275,16 @@ namespace ROOT {

// rotation and transformations


/**
rotation along X axis for a generic vector by an Angle alpha
returning a new vector.
The only pre requisite on the Vector is that it has to implement the X() , Y() and Z()
The only pre requisite on the Vector is that it has to implement the X(), Y() and Z()
and SetXYZ methods.
*/
template <class Vector>
Vector RotateX(const Vector & v, double alpha) {
if (std::fmod(alpha, 2 * M_PI) == 0.)
return v;
using std::sin;
double sina = sin(alpha);
using std::cos;
Expand All @@ -298,11 +299,13 @@ namespace ROOT {
/**
rotation along Y axis for a generic vector by an Angle alpha
returning a new vector.
The only pre requisite on the Vector is that it has to implement the X() , Y() and Z()
The only pre requisite on the Vector is that it has to implement the X(), Y() and Z()
and SetXYZ methods.
*/
template <class Vector>
Vector RotateY(const Vector & v, double alpha) {
if (std::fmod(alpha, 2 * M_PI) == 0.)
return v;
using std::sin;
double sina = sin(alpha);
using std::cos;
Expand All @@ -317,11 +320,13 @@ namespace ROOT {
/**
rotation along Z axis for a generic vector by an Angle alpha
returning a new vector.
The only pre requisite on the Vector is that it has to implement the X() , Y() and Z()
The only pre requisite on the Vector is that it has to implement the X(), Y() and Z()
and SetXYZ methods.
*/
template <class Vector>
Vector RotateZ(const Vector & v, double alpha) {
if (std::fmod(alpha, 2 * M_PI) == 0.)
return v;
using std::sin;
double sina = sin(alpha);
using std::cos;
Expand All @@ -333,6 +338,40 @@ namespace ROOT {
return vrot;
}

/**
rotation along a custom axis for a generic vector by an Angle alpha (in rad)
returning a new vector.
The only pre requisite on the Vector is that it has to implement the X(), Y() and Z()
and SetXYZ methods.
*/
template <class Vector>
Vector Rotate(const Vector &v, double alpha, const Vector &axis)
{
if (std::fmod(alpha, 2 * M_PI) == 0.)
return v;
const double ll = std::sqrt(axis.X() * axis.X() + axis.Y() * axis.Y() + axis.Z() * axis.Z());
if (ll == 0.)
GenVector::Throw("Axis Vector has zero magnitude");
const double sa = std::sin(alpha);
const double ca = std::cos(alpha);
const double dx = axis.X() / ll;
const double dy = axis.Y() / ll;
const double dz = axis.Z() / ll;
const double rot00 = (1 - ca) * dx * dx + ca, rot01 = (1 - ca) * dx * dy - sa * dz,
rot02 = (1 - ca) * dx * dz + sa * dy, rot10 = (1 - ca) * dy * dx + sa * dz,
rot11 = (1 - ca) * dy * dy + ca, rot12 = (1 - ca) * dy * dz - sa * dx,
rot20 = (1 - ca) * dz * dx - sa * dy, rot21 = (1 - ca) * dz * dy + sa * dx,
rot22 = (1 - ca) * dz * dz + ca;
const double xX = v.X();
const double yY = v.Y();
const double zZ = v.Z();
const double x2 = rot00 * xX + rot01 * yY + rot02 * zZ;
const double y2 = rot10 * xX + rot11 * yY + rot12 * zZ;
const double z2 = rot20 * xX + rot21 * yY + rot22 * zZ;
Vector vrot;
vrot.SetXYZ(x2, y2, z2);
return vrot;
}

/**
rotation on a generic vector using a generic rotation class.
Expand Down
3 changes: 2 additions & 1 deletion math/physics/src/TRotation.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ TVector3 class:
#include "TRotation.h"
#include "TMath.h"
#include "TQuaternion.h"
#include <cmath>

ClassImp(TRotation);

Expand Down Expand Up @@ -323,7 +324,7 @@ TRotation::TRotation(const TQuaternion & Q) {
/// Rotate along an axis.

TRotation & TRotation::Rotate(Double_t a, const TVector3& axis) {
if (a != 0.0) {
if (std::fmod(a, 2 * M_PI) != 0.) {
Double_t ll = axis.Mag();
if (ll == 0.0) {
Warning("Rotate(angle,axis)"," zero axis");
Expand Down
Loading