1 // -*- C++ -*- 2 // CLASSDOC OFF 3 // $Id: Rotation.h,v 1.3 2003/10/23 21:29:52 garren Exp $ 4 // --------------------------------------------------------------------------- 5 // CLASSDOC ON 6 // 7 // This file is a part of the CLHEP - a Class Library for High Energy Physics. 8 // 9 // This is the definition of the HepRotation class for performing rotations 10 // on objects of the Hep3Vector (and HepLorentzVector) class. 11 // 12 // HepRotation is a concrete implementation of Hep3RotationInterface. 13 // 14 // .SS See Also 15 // RotationInterfaces.h 16 // ThreeVector.h, LorentzVector.h, LorentzRotation.h 17 // 18 // .SS Author 19 // Leif Lonnblad, Mark Fischler 20 21 #ifndef HEP_ROTATION_H 22 #define HEP_ROTATION_H 23 24 #ifdef GNUPRAGMA 25 #pragma interface 26 #endif 27 28 #include "CLHEP/Vector/defs.h" 29 #include "CLHEP/Vector/RotationInterfaces.h" 30 #include "CLHEP/Vector/RotationX.h" 31 #include "CLHEP/Vector/RotationY.h" 32 #include "CLHEP/Vector/RotationZ.h" 33 #include "CLHEP/Vector/LorentzVector.h" 34 35 namespace CLHEP { 36 37 // Declarations of classes and global methods 38 class HepRotation; 39 inline HepRotation inverseOf ( const HepRotation & r ); 40 inline HepRotation operator * (const HepRotationX & rx, const HepRotation & r); 41 inline HepRotation operator * (const HepRotationY & ry, const HepRotation & r); 42 inline HepRotation operator * (const HepRotationZ & rz, const HepRotation & r); 43 44 /** 45 * @author 46 * @ingroup vector 47 */ 48 class HepRotation { 49 50 public: 51 52 // ---------- Constructors and Assignment: 53 54 inline HepRotation(); 55 // Default constructor. Gives a unit matrix. 56 57 inline HepRotation(const HepRotation & m); 58 // Copy constructor. 59 60 inline HepRotation(const HepRotationX & m); 61 inline HepRotation(const HepRotationY & m); 62 inline HepRotation(const HepRotationZ & m); 63 // Construct from specialized rotation. 64 65 HepRotation & set( const Hep3Vector & axis, double delta ); 66 HepRotation ( const Hep3Vector & axis, double delta ); 67 // Construct from axis and angle. 68 69 HepRotation & set( const HepAxisAngle & ax ); 70 HepRotation ( const HepAxisAngle & ax ); 71 // Construct from AxisAngle structure. 72 73 HepRotation & set( double phi, double theta, double psi ); 74 HepRotation ( double phi, double theta, double psi ); 75 // Construct from three Euler angles (in radians). 76 77 HepRotation & set( const HepEulerAngles & e ); 78 HepRotation ( const HepEulerAngles & e ); 79 // Construct from EulerAngles structure. 80 81 HepRotation ( const Hep3Vector & colX, 82 const Hep3Vector & colY, 83 const Hep3Vector & colZ ); 84 // Construct from three *orthogonal* unit vector columns. 85 // NOTE: 86 // This constructor, and the two set methods below, 87 // will check that the columns (or rows) form an orthonormal 88 // matrix, and will adjust values so that this relation is 89 // as exact as possible. 90 91 HepRotation & set( const Hep3Vector & colX, 92 const Hep3Vector & colY, 93 const Hep3Vector & colZ ); 94 // supply three *orthogonal* unit vectors for the columns. 95 96 HepRotation & setRows( const Hep3Vector & rowX, 97 const Hep3Vector & rowY, 98 const Hep3Vector & rowZ ); 99 // supply three *orthogonal* unit vectors for the rows. 100 101 inline HepRotation & set(const HepRotationX & r); 102 inline HepRotation & set(const HepRotationY & r); 103 inline HepRotation & set(const HepRotationZ & r); 104 // set from specialized rotation. 105 106 inline HepRotation & operator = (const HepRotation & r); 107 // Assignment. 108 109 inline HepRotation & operator = (const HepRotationX & r); 110 inline HepRotation & operator = (const HepRotationY & r); 111 inline HepRotation & operator = (const HepRotationZ & r); 112 // Assignment from specialized rotation. 113 114 inline HepRotation &set( const HepRep3x3 & m ); 115 inline HepRotation ( const HepRep3x3 & m ); 116 // WARNING - NO CHECKING IS DONE! 117 // Constructon directly from from a 3x3 representation, 118 // which is required to be an orthogonal matrix. 119 120 inline ~HepRotation(); 121 // Trivial destructor. 122 123 // ---------- Accessors: 124 125 inline Hep3Vector colX() const; 126 inline Hep3Vector colY() const; 127 inline Hep3Vector colZ() const; 128 // orthogonal unit-length column vectors 129 130 inline Hep3Vector rowX() const; 131 inline Hep3Vector rowY() const; 132 inline Hep3Vector rowZ() const; 133 // orthogonal unit-length row vectors 134 135 inline double xx() const; 136 inline double xy() const; 137 inline double xz() const; 138 inline double yx() const; 139 inline double yy() const; 140 inline double yz() const; 141 inline double zx() const; 142 inline double zy() const; 143 inline double zz() const; 144 // Elements of the rotation matrix (Geant4). 145 146 inline HepRep3x3 rep3x3() const; 147 // 3x3 representation: 148 149 // ------------ Subscripting: 150 151 class HepRotation_row { 152 public: 153 inline HepRotation_row(const HepRotation &, int); 154 inline double operator [] (int) const; 155 private: 156 const HepRotation & rr; 157 int ii; 158 }; 159 // Helper class for implemention of C-style subscripting r[i][j] 160 161 inline const HepRotation_row operator [] (int) const; 162 // Returns object of the helper class for C-style subscripting r[i][j] 163 // i and j range from 0 to 2. 164 165 double operator () (int, int) const; 166 // Fortran-style subscripting: returns (i,j) element of the rotation matrix. 167 // Note: i and j still range from 0 to 2. [Rotation.cc] 168 169 // ------------ Euler angles: 170 inline double getPhi () const; 171 inline double getTheta() const; 172 inline double getPsi () const; 173 double phi () const; 174 double theta() const; 175 double psi () const; 176 HepEulerAngles eulerAngles() const; 177 178 // ------------ axis & angle of rotation: 179 inline double getDelta() const; 180 inline Hep3Vector getAxis () const; 181 double delta() const; 182 Hep3Vector axis () const; 183 HepAxisAngle axisAngle() const; 184 void getAngleAxis(double & delta, Hep3Vector & axis) const; 185 // Returns the rotation angle and rotation axis (Geant4). [Rotation.cc] 186 187 // ------------- Angles of rotated axes 188 double phiX() const; 189 double phiY() const; 190 double phiZ() const; 191 double thetaX() const; 192 double thetaY() const; 193 double thetaZ() const; 194 // Return angles (RADS) made by rotated axes against original axes (Geant4). 195 // [Rotation.cc] 196 197 // ---------- Other accessors treating pure rotation as a 4-rotation 198 199 inline HepLorentzVector col1() const; 200 inline HepLorentzVector col2() const; 201 inline HepLorentzVector col3() const; 202 // orthosymplectic 4-vector columns - T component will be zero 203 204 inline HepLorentzVector col4() const; 205 // Will be (0,0,0,1) for this pure Rotation. 206 207 inline HepLorentzVector row1() const; 208 inline HepLorentzVector row2() const; 209 inline HepLorentzVector row3() const; 210 // orthosymplectic 4-vector rows - T component will be zero 211 212 inline HepLorentzVector row4() const; 213 // Will be (0,0,0,1) for this pure Rotation. 214 215 inline double xt() const; 216 inline double yt() const; 217 inline double zt() const; 218 inline double tx() const; 219 inline double ty() const; 220 inline double tz() const; 221 // Will be zero for this pure Rotation 222 223 inline double tt() const; 224 // Will be one for this pure Rotation 225 226 inline HepRep4x4 rep4x4() const; 227 // 4x4 representation. 228 229 // --------- Mutators 230 231 void setPhi (double phi); 232 // change Euler angle phi, leaving theta and psi unchanged. 233 234 void setTheta (double theta); 235 // change Euler angle theta, leaving phi and psi unchanged. 236 237 void setPsi (double psi); 238 // change Euler angle psi, leaving theta and phi unchanged. 239 240 void setAxis (const Hep3Vector & axis); 241 // change rotation axis, leaving delta unchanged. 242 243 void setDelta (double delta); 244 // change angle of rotation, leaving rotation axis unchanged. 245 246 // ---------- Decomposition: 247 248 void decompose (HepAxisAngle & rotation, Hep3Vector & boost) const; 249 void decompose (Hep3Vector & boost, HepAxisAngle & rotation) const; 250 // These are trivial, as the boost vector is 0. [RotationP.cc] 251 252 // ---------- Comparisons: 253 254 bool isIdentity() const; 255 // Returns true if the identity matrix (Geant4). [Rotation.cc] 256 257 int compare( const HepRotation & r ) const; 258 // Dictionary-order comparison, in order zz, zy, zx, yz, ... xx 259 // Used in operator<, >, <=, >= 260 261 inline bool operator== ( const HepRotation & r ) const; 262 inline bool operator!= ( const HepRotation & r ) const; 263 inline bool operator< ( const HepRotation & r ) const; 264 inline bool operator> ( const HepRotation & r ) const; 265 inline bool operator<= ( const HepRotation & r ) const; 266 inline bool operator>= ( const HepRotation & r ) const; 267 268 double distance2( const HepRotation & r ) const; 269 // 3 - Tr ( this/r ) -- This works with RotationX, Y or Z also 270 271 double howNear( const HepRotation & r ) const; 272 bool isNear( const HepRotation & r, 273 double epsilon=Hep4RotationInterface::tolerance) const; 274 275 double distance2( const HepBoost & lt ) const; 276 // 3 - Tr ( this ) + |b|^2 / (1-|b|^2) 277 double distance2( const HepLorentzRotation & lt ) const; 278 // 3 - Tr ( this/r ) + |b|^2 / (1-|b|^2) where b is the boost vector of lt 279 280 double howNear( const HepBoost & lt ) const; 281 double howNear( const HepLorentzRotation & lt ) const; 282 bool isNear( const HepBoost & lt, 283 double epsilon=Hep4RotationInterface::tolerance) const; 284 bool isNear( const HepLorentzRotation & lt, 285 double epsilon=Hep4RotationInterface::tolerance) const; 286 287 // ---------- Properties: 288 289 double norm2() const; 290 // distance2 (IDENTITY), which is 3 - Tr ( *this ) 291 292 void rectify(); 293 // non-const but logically moot correction for accumulated roundoff errors 294 // rectify averages the matrix with the transpose of its actual 295 // inverse (absent accumulated roundoff errors, the transpose IS 296 // the inverse)); this removes to first order those errors. 297 // Then it formally extracts axis and delta, and forms a true 298 // HepRotation with those values of axis and delta. 299 300 // ---------- Application: 301 302 inline Hep3Vector operator() (const Hep3Vector & p) const; 303 // Rotate a Hep3Vector. 304 305 inline Hep3Vector operator * (const Hep3Vector & p) const; 306 // Multiplication with a Hep3Vector. 307 308 inline HepLorentzVector operator()( const HepLorentzVector & w ) const; 309 // Rotate (the space part of) a HepLorentzVector. 310 311 inline HepLorentzVector operator* ( const HepLorentzVector & w ) const; 312 // Multiplication with a HepLorentzVector. 313 314 // ---------- Operations in the group of Rotations 315 316 inline HepRotation operator * (const HepRotation & r) const; 317 // Product of two rotations (this) * r - matrix multiplication 318 319 inline HepRotation operator * (const HepRotationX & rx) const; 320 inline HepRotation operator * (const HepRotationY & ry) const; 321 inline HepRotation operator * (const HepRotationZ & rz) const; 322 // Product of two rotations (this) * r - faster when specialized type 323 324 inline HepRotation & operator *= (const HepRotation & r); 325 inline HepRotation & transform (const HepRotation & r); 326 // Matrix multiplication. 327 // Note a *= b; <=> a = a * b; while a.transform(b); <=> a = b * a; 328 329 inline HepRotation & operator *= (const HepRotationX & r); 330 inline HepRotation & operator *= (const HepRotationY & r); 331 inline HepRotation & operator *= (const HepRotationZ & r); 332 inline HepRotation & transform (const HepRotationX & r); 333 inline HepRotation & transform (const HepRotationY & r); 334 inline HepRotation & transform (const HepRotationZ & r); 335 // Matrix multiplication by specialized matrices 336 337 HepRotation & rotateX(double delta); 338 // Rotation around the x-axis; equivalent to R = RotationX(delta) * R 339 340 HepRotation & rotateY(double delta); 341 // Rotation around the y-axis; equivalent to R = RotationY(delta) * R 342 343 HepRotation & rotateZ(double delta); 344 // Rotation around the z-axis; equivalent to R = RotationZ(delta) * R 345 346 HepRotation & rotate(double delta, const Hep3Vector & axis); 347 inline HepRotation & rotate(double delta, const Hep3Vector * axis); 348 // Rotation around a specified vector. 349 // r.rotate(d,a) is equivalent to r = Rotation(d,a) * r 350 351 HepRotation & rotateAxes(const Hep3Vector & newX, 352 const Hep3Vector & newY, 353 const Hep3Vector & newZ); 354 // Rotation of local axes defined by 3 orthonormal vectors (Geant4). 355 // Equivalent to r = Rotation (newX, newY, newZ) * r 356 357 inline HepRotation inverse() const; 358 // Returns the inverse. 359 360 inline HepRotation & invert(); 361 // Inverts the Rotation matrix. 362 363 // ---------- I/O: 364 365 std::ostream & print( std::ostream & os ) const; 366 // Aligned six-digit-accurate output of the rotation matrix. [RotationIO.cc] 367 368 // ---------- Identity Rotation: 369 370 static const HepRotation IDENTITY; 371 372 // ---------- Tolerance 373 374 static inline double getTolerance(); 375 static inline double setTolerance(double tol); 376 377 protected: 378 379 inline HepRotation(double mxx, double mxy, double mxz, 380 double myx, double myy, double myz, 381 double mzx, double mzy, double mzz); 382 // Protected constructor. 383 // DOES NOT CHECK FOR VALIDITY AS A ROTATION. 384 385 friend HepRotation operator* (const HepRotationX & rx, const HepRotation & r); 386 friend HepRotation operator* (const HepRotationY & ry, const HepRotation & r); 387 friend HepRotation operator* (const HepRotationZ & rz, const HepRotation & r); 388 389 double rxx, rxy, rxz, 390 ryx, ryy, ryz, 391 rzx, rzy, rzz; 392 // The matrix elements. 393 394 private: 395 bool 396 setCols ( const Hep3Vector & u1, // Vectors assume to be of unit length 397 const Hep3Vector & u2, 398 const Hep3Vector & u3, 399 double u1u2, 400 Hep3Vector & v1, // Returned vectors 401 Hep3Vector & v2, 402 Hep3Vector & v3 ) const; 403 void setArbitrarily (const Hep3Vector & colX, // assumed to be of unit length 404 Hep3Vector & v1, 405 Hep3Vector & v2, 406 Hep3Vector & v3) const; 407 }; // HepRotation 408 409 inline 410 std::ostream & operator << 411 ( std::ostream & os, const HepRotation & r ) {return r.print(os);} 412 413 } // namespace CLHEP 414 415 #include "CLHEP/Vector/Rotation.icc" 416 417 #ifdef ENABLE_BACKWARDS_COMPATIBILITY 418 // backwards compatibility will be enabled ONLY in CLHEP 1.9 419 using namespace CLHEP; 420 #endif 421 422 #endif /* HEP_ROTATION_H */ 423 424