// @(#)root/mathcore:$Id$ // Authors: W. Brown, M. Fischler, L. Moneta 2005 /********************************************************************** * * * Copyright (c) 2005 , LCG ROOT FNAL MathLib Team * * * * * **********************************************************************/ // Header file for class AxisAngle, a rotation in 3 dimensions // represented by its axis and angle of rotation // // Created by: Mark Fischler Tues July 5 2005 // #include "Math/GenVector/AxisAngle.h" #include #include #include "Math/GenVector/Cartesian3D.h" #include "Math/GenVector/DisplacementVector3D.h" #include "Math/GenVector/Rotation3D.h" namespace ROOT { namespace Math { // ========== Constructors and Assignment ===================== void AxisAngle::RectifyAngle() { // Note: We could require the angle to be in [0,pi) since we // can represent negative angles by flipping the axis. // We choose not to do this. if ( fAngle <= Pi() && fAngle > -Pi() ) return; if ( fAngle > 0 ) { int n = static_cast( (fAngle+Pi())/(2*Pi()) ); fAngle -= 2*Pi()*n; } else { int n = static_cast( -(fAngle-Pi())/(2*Pi()) ); fAngle += 2*Pi()*n; } } // RectifyAngle() void AxisAngle::Rectify() { // The two conditions are that the angle is in (-pi, pi] and // the axis is a unit vector. Scalar r2 = fAxis.Mag2(); if ( r2 == 0 ) { fAxis.SetCoordinates(0,0,1); fAngle = 0; return; } fAxis *= (1.0/r2); RectifyAngle(); } // Rectify() // ======== Transformation to other Rotation Forms ================== enum ERotation3DMatrixIndex { kXX = 0, kXY = 1, kXZ = 2 , kYX = 3, kYY = 4, kYZ = 5 , kZX = 6, kZY = 7, kZZ = 8 }; // ========== Operations ===================== DisplacementVector3D< Cartesian3D > AxisAngle:: operator() (const DisplacementVector3D< Cartesian3D > & v) const { Scalar c = std::cos(fAngle); Scalar s = std::sin(fAngle); Scalar p = fAxis.Dot(v) * ( 1 - c ); return DisplacementVector3D< Cartesian3D > ( c*v.X() + p*fAxis.X() + s * (fAxis.Y()*v.Z() - fAxis.Z()*v.Y()) , c*v.Y() + p*fAxis.Y() + s * (fAxis.Z()*v.X() - fAxis.X()*v.Z()) , c*v.Z() + p*fAxis.Z() + s * (fAxis.X()*v.Y() - fAxis.Y()*v.X()) ); } // ========== I/O ===================== std::ostream & operator<< (std::ostream & os, const AxisAngle & a) { // TODO - this will need changing for machine-readable issues // and even the human readable form may need formatiing improvements os << "\n" << a.Axis() << " " << a.Angle() << "\n"; return os; } } //namespace Math } //namespace ROOT