CLHEP/Geometry/Transform3D.h

00001 // -*- C++ -*-
00002 // $Id: Transform3D.h,v 1.13 2002/04/19 16:33:40 evc Exp $
00003 // ---------------------------------------------------------------------------
00004 //
00005 // This file is a part of the CLHEP - a Class Library for High Energy Physics.
00006 //
00007 // Hep geometrical 3D Transformation class
00008 //
00009 // Author: Evgeni Chernyaev <Evgueni.Tcherniaev@cern.ch>
00010 //
00011 //          ******************************************
00012 //          *                                        *
00013 //          *               Transform                *
00014 //          *               /  / \  \                *
00015 //          *       --------  /   \  --------        *
00016 //          *      /         /     \         \       *
00017 //          *   Rotate Translate  Reflect   Scale    *
00018 //          *    / | \    / | \    / | \    / | \    *
00019 //          *   X  Y  Z  X  Y  Z  X  Y  Z  X  Y  Z   *
00020 //          *                                        *
00021 //          ******************************************
00022 //
00023 // Identity transformation:
00024 //   HepTransform3D::Identity   - global identity transformation;
00025 //   any constructor without parameters, e.g. HepTransform3D();
00026 //   m.setIdentity()            - set "m" to identity;
00027 //
00028 // General transformations:
00029 //   HepTransform3D(m,v)         - transformation given by HepRotation "m"
00030 //                                 and Hep3Vector "v";
00031 //   HepTransform3D(a0,a1,a2, b0,b1,b2) - transformation given by initial
00032 //                                 and transformed positions of three points;
00033 // Rotations:
00034 //   HepRotate3D(m)              - rotation given by HepRotation "m";
00035 //   HepRotate3D(ang,v)          - rotation through the angle "ang" around
00036 //                                 vector "v";
00037 //   HepRotate3D(ang,p1,p2)      - rotation through the angle "ang"
00038 //                                 counterclockwise around the axis given by
00039 //                                 two points p1->p2;
00040 //   HepRotate3D(a1,a2, b1,b2)   - rotation around the origin defined by initial
00041 //                                 and transformed positions of two points;
00042 //   HepRotateX3D(ang)           - rotation around X-axis;
00043 //   HepRotateY3D(ang)           - rotation around Y-axis;
00044 //   HepRotateZ3D(ang)           - rotation around Z-axis;
00045 //
00046 // Translations:
00047 //   HepTranslate3D(v)           - translation given by Hep3Vector "v";
00048 //   HepTranslate3D(dx,dy,dz)    - translation on vector (dx,dy,dz);
00049 //   HepTraslateX3D(dx)          - translation along X-axis;
00050 //   HepTraslateY3D(dy)          - translation along Y-axis;
00051 //   HepTraslateZ3D(dz)          - translation along Z-axis;
00052 //
00053 // Reflections:
00054 //   HepReflect3D(a,b,c,d)       - reflection in the plane a*x+b*y+c*z+d=0;
00055 //   HepReflect3D(normal,p)      - reflection in the plane going through "p"
00056 //                                 and whose normal is equal to "normal";
00057 //   HepReflectX3D(a)            - reflect X in the plane x=a (default a=0);
00058 //   HepReflectY3D(a)            - reflect Y in the plane y=a (default a=0);
00059 //   HepReflectZ3D(a)            - reflect Z in the plane z=a (default a=0);
00060 //
00061 // Scalings:
00062 //   HepScale3D(sx,sy,sz)        - general scaling with factors "sx","sy","sz"
00063 //                                 along X, Y and Z;
00064 //   HepScale3D(s)               - scaling with constant factor "s" along all 
00065 //                                 directions;
00066 //   HepScaleX3D(sx)             - scale X;
00067 //   HepScaleY3D(sy)             - scale Y;
00068 //   HepScaleZ3D(sz)             - scale Z;
00069 //
00070 // Inverse transformation:
00071 //   m.inverse() or             - returns inverse transformation;
00072 //
00073 // Compound transformation:
00074 //   m3 = m2 * m1               - it is relatively slow in comparison with
00075 //                                transformation of a vector. Use parenthesis
00076 //                                to avoid this operation (see remark below);
00077 // Transformation of point:
00078 //   p2 = m * p1
00079 //
00080 // Transformation of vector:
00081 //   v2 = m * v1
00082 //
00083 // Transformation of normal:
00084 //   n2 = m * n1
00085 //
00086 // The following table explains how different transformations affect
00087 // point, vector and normal. "+" means affect, "-" means do not affect,
00088 // "*" meas affect but in different way than "+" 
00089 //
00090 //                     Point  Vector  Normal
00091 //      -------------+-------+-------+-------
00092 //       Rotation    !   +   !   +   !   +
00093 //       Translation !   +   !   -   !   -
00094 //       Reflection  !   +   !   +   !   *
00095 //       Scaling     !   +   !   +   !   *
00096 //      -------------+-------+-------+-------
00097 //
00098 // Example of the usage:
00099 //
00100 //   HepTransform3D m1, m2, m3;
00101 //   HepVector3D    v2, v1(0,0,0);
00102 //
00103 //   m1 = HepRotate3D(angle, HepVector3D(1,1,1));
00104 //   m2 = HepTranslate3D(dx,dy,dz);
00105 //   m3 = m1^-1;
00106 //
00107 //   v2 = m3*(m2*(m1*v1));
00108 //
00109 // History:
00110 // 24.09.96 E.Chernyaev - initial version
00111 //
00112 // 26.02.97 E.Chernyaev
00113 // - added global Identity by request of John Allison 
00114 //   (to avoid problems with compilation on HP) 
00115 // - added getRotation and getTranslation 
00116 //
00117 // 29.01.01 E.Chernyaev - added subscripting
00118 // 11.06.01 E.Chernyaev - added getDecomposition
00119 
00120 #ifndef HEP_TRANSFROM3D_H
00121 #define HEP_TRANSFROM3D_H
00122 
00123 #include "CLHEP/config/CLHEP.h"
00124 
00125 class Hep3Vector;
00126 class HepRotation;
00127 class HepPoint3D;
00128 class HepVector3D;
00129 class HepNormal3D;
00130 
00131 class HepTranslate3D;
00132 class HepRotate3D;
00133 class HepScale3D;
00134 
00171 class HepTransform3D {
00172  protected:
00173   double xx, xy, xz, dx,     // 4x3  Transformation Matrix
00174          yx, yy, yz, dy,
00175          zx, zy, zz, dz;
00176 
00177   // Protected constructor
00178   HepTransform3D(double XX, double XY, double XZ, double DX,
00179                  double YX, double YY, double YZ, double DY,
00180                  double ZX, double ZY, double ZZ, double DZ)
00181     : xx(XX), xy(XY), xz(XZ), dx(DX),
00182       yx(YX), yy(YY), yz(YZ), dy(DY),
00183       zx(ZX), zy(ZY), zz(ZZ), dz(DZ) {}
00184 
00185   // Set transformation matrix
00186   void setTransform(double XX, double XY, double XZ, double DX,
00187                     double YX, double YY, double YZ, double DY,
00188                     double ZX, double ZY, double ZZ, double DZ) {
00189     xx = XX; xy = XY; xz = XZ; dx = DX;
00190     yx = YX; yy = YY; yz = YZ; dy = DY;
00191     zx = ZX; zy = ZY; zz = ZZ; dz = DZ;
00192   }
00193 
00194  public:
00196   static const HepTransform3D Identity;
00197 
00198   // Helper class for implemention of C-style subscripting r[i][j] 
00199   class HepTransform3D_row {
00200   public:
00201     inline HepTransform3D_row(const HepTransform3D &, int);
00202     inline double operator [] (int) const;
00203   private:
00204     const HepTransform3D & rr;
00205     int ii;
00206   };
00207 
00209   HepTransform3D()
00210     : xx(1), xy(0), xz(0), dx(0),
00211       yx(0), yy(1), yz(0), dy(0),
00212       zx(0), zy(0), zz(1), dz(0) {}
00213   
00215   inline HepTransform3D(const HepRotation &m, const Hep3Vector &v);
00216 
00218   HepTransform3D
00219   (const HepPoint3D &fr0, const HepPoint3D &fr1, const HepPoint3D &fr2,
00220    const HepPoint3D &to0, const HepPoint3D &to1, const HepPoint3D &to2);
00221 
00223   HepTransform3D(const HepTransform3D & m)
00224     : xx(m.xx), xy(m.xy), xz(m.xz), dx(m.dx),
00225       yx(m.yx), yy(m.yy), yz(m.yz), dy(m.dy),
00226       zx(m.zx), zy(m.zy), zz(m.zz), dz(m.dz) {}
00227 
00229   inline const HepTransform3D_row operator [] (int) const; 
00230 
00232   double operator () (int, int) const;
00233 
00235   HepTransform3D& operator=(const HepTransform3D &m) {
00236     setTransform(m.xx, m.xy, m.xz, m.dx,
00237                  m.yx, m.yy, m.yz, m.dy,
00238                  m.zx, m.zy, m.zz, m.dz);
00239     return *this;
00240   }
00241 
00243   void setIdentity() { 
00244     xy = xz = dx = yx = yz = dy = zx = zy = dz = 0; xx = yy = zz = 1;
00245   }
00246 
00248   HepTransform3D inverse() const;
00249 
00251   inline HepTransform3D operator*(const HepTransform3D &b) const;
00252 
00254   inline HepPoint3D operator*(const HepPoint3D &p) const;
00255 
00257   inline HepVector3D operator*(const HepVector3D &v) const;
00258 
00260   inline HepNormal3D operator*(const HepNormal3D &n) const;
00261 
00277   void getDecomposition(HepScale3D & scale,
00278                         HepRotate3D & rotation,
00279                         HepTranslate3D & translation) const;
00280 
00285   inline HepRotation getRotation() const;
00286 
00291   inline Hep3Vector getTranslation() const;
00292 
00294   bool operator == (const HepTransform3D & transform) const {
00295     return this == &transform ? true : false;
00296   }
00297 
00299   bool operator != (const HepTransform3D & transform) const {
00300     return this != &transform ? true : false;
00301   }
00302 };
00303 
00304 //   R O T A T I O N S
00305 
00320 class HepRotate3D : public HepTransform3D {
00321  public:
00323   HepRotate3D() : HepTransform3D() {}
00324 
00326   inline HepRotate3D(const HepRotation &m);
00327 
00334   HepRotate3D(double a, const HepPoint3D &p1, const HepPoint3D &p2);
00335 
00341   inline HepRotate3D(double a, const HepVector3D &v);
00342 
00351   inline HepRotate3D(const HepPoint3D &fr1, const HepPoint3D &fr2,
00352                      const HepPoint3D &to1, const HepPoint3D &to2);
00353 };
00354 
00369 class HepRotateX3D : public HepRotate3D {
00370  public:
00372   HepRotateX3D() : HepRotate3D() {}
00374   HepRotateX3D(double a) {
00375     double cosa = cos(a), sina = sin(a); 
00376     setTransform(1,0,0,0,  0,cosa,-sina,0,  0,sina,cosa,0);
00377   }
00378 };
00379 
00394 class HepRotateY3D : public HepRotate3D {
00395  public:
00397   HepRotateY3D() : HepRotate3D() {}
00399   HepRotateY3D(double a) {
00400     double cosa = cos(a), sina = sin(a); 
00401     setTransform(cosa,0,sina,0,  0,1,0,0,  -sina,0,cosa,0);
00402   }
00403 };
00404 
00419 class HepRotateZ3D : public HepRotate3D {
00420  public:
00422   HepRotateZ3D() : HepRotate3D() {}
00424   HepRotateZ3D(double a) {
00425     double cosa = cos(a), sina = sin(a); 
00426     setTransform(cosa,-sina,0,0,  sina,cosa,0,0,  0,0,1,0);
00427   }
00428 };
00429 
00430 //   T R A N S L A T I O N S
00431 
00446 class HepTranslate3D : public HepTransform3D {
00447  public:
00449   HepTranslate3D() : HepTransform3D() {}
00451   inline HepTranslate3D(const Hep3Vector &v);
00453   HepTranslate3D(double x, double y, double z)
00454     : HepTransform3D(1,0,0,x, 0,1,0,y, 0,0,1,z) {}
00455 };
00456 
00471 class HepTranslateX3D : public HepTranslate3D {
00472  public:
00474   HepTranslateX3D() : HepTranslate3D() {}
00476   HepTranslateX3D(double x) : HepTranslate3D(x, 0, 0) {}
00477 };
00478 
00493 class HepTranslateY3D : public HepTranslate3D {
00494  public:
00496   HepTranslateY3D() : HepTranslate3D() {}
00498   HepTranslateY3D(double y) : HepTranslate3D(0, y, 0) {}
00499 };
00500 
00515 class HepTranslateZ3D : public HepTranslate3D {
00516  public:
00518   HepTranslateZ3D() : HepTranslate3D() {}
00520   HepTranslateZ3D(double z) : HepTranslate3D(0, 0, z) {}
00521 };
00522 
00523 //   R E F L E C T I O N S
00524 
00539 class HepReflect3D : public HepTransform3D {
00540  protected:
00541   HepReflect3D(double XX, double XY, double XZ, double DX,
00542                double YX, double YY, double YZ, double DY,
00543                double ZX, double ZY, double ZZ, double DZ)
00544     : HepTransform3D(XX,XY,XZ,DX, YX,YY,YZ,DY, ZX,ZY,ZZ,DZ) {}
00545 
00546  public:
00548   HepReflect3D() : HepTransform3D() {}
00550   HepReflect3D(double a, double b, double c, double d);
00551   inline HepReflect3D(const HepNormal3D &normal, const HepPoint3D &point);
00552 };
00553 
00568 class HepReflectX3D : public HepReflect3D {
00569  public:
00571   HepReflectX3D(double x=0) : HepReflect3D(-1,0,0,x+x, 0,1,0,0, 0,0,1,0) {}
00572 };
00573  
00588 class HepReflectY3D : public HepReflect3D {
00589  public:
00591   HepReflectY3D(double y=0) : HepReflect3D(1,0,0,0, 0,-1,0,y+y, 0,0,1,0) {}
00592 };
00593  
00608 class HepReflectZ3D : public HepReflect3D {
00609  public:
00611   HepReflectZ3D(double z=0) : HepReflect3D(1,0,0,0, 0,1,0,0, 0,0,-1,z+z) {}
00612 };
00613  
00614 //   S C A L I N G S
00615 
00630 class HepScale3D : public HepTransform3D {
00631  public:
00633   HepScale3D() : HepTransform3D() {}
00635   HepScale3D(double x, double y, double z)
00636     : HepTransform3D(x,0,0,0, 0,y,0,0, 0,0,z,0) {}
00638   HepScale3D(double s)
00639     : HepTransform3D(s,0,0,0, 0,s,0,0, 0,0,s,0) {}
00640 };
00641 
00656 class HepScaleX3D : public HepScale3D {
00657  public:
00659   HepScaleX3D() : HepScale3D() {}
00661   HepScaleX3D(double x) : HepScale3D(x, 1, 1) {}
00662 };
00663 
00678 class HepScaleY3D : public HepScale3D {
00679  public:
00681   HepScaleY3D() : HepScale3D() {}
00683   HepScaleY3D(double y) : HepScale3D(1, y, 1) {}
00684 };
00685 
00700 class HepScaleZ3D : public HepScale3D {
00701  public:
00703   HepScaleZ3D() : HepScale3D() {}
00705   HepScaleZ3D(double z) : HepScale3D(1, 1, z) {}
00706 };
00707 
00708 //   I N L I N E S   F O R   T R A N S F O R M A T I O N
00709 
00710 #include "CLHEP/Vector/ThreeVector.h"
00711 #include "CLHEP/Vector/Rotation.h"
00712 #include "CLHEP/Geometry/Point3D.h"
00713 #include "CLHEP/Geometry/Vector3D.h"
00714 #include "CLHEP/Geometry/Normal3D.h"
00715 
00716 inline
00717 HepTransform3D::HepTransform3D_row::HepTransform3D_row
00718 (const HepTransform3D & r, int i) : rr(r), ii(i) {}
00719 
00720 inline
00721 double HepTransform3D::HepTransform3D_row::operator[](int jj) const {
00722   return rr(ii,jj);
00723 }
00724 
00725 inline const HepTransform3D::HepTransform3D_row
00726 HepTransform3D::operator[](int i) const {
00727   return HepTransform3D_row(*this, i);
00728 }
00729 
00730 inline
00731 HepTransform3D::HepTransform3D(const HepRotation &m, const Hep3Vector &v) {
00732   Hep3Vector w;
00733   w = m * Hep3Vector(1,0,0); xx = w.x(); yx = w.y(); zx = w.z();
00734   w = m * Hep3Vector(0,1,0); xy = w.x(); yy = w.y(); zy = w.z();
00735   w = m * Hep3Vector(0,0,1); xz = w.x(); yz = w.y(); zz = w.z();
00736   dx = v.x(); dy = v.y(); dz = v.z();
00737 }
00738 
00739 inline
00740 HepTransform3D HepTransform3D::operator*(const HepTransform3D &b) const {
00741   return HepTransform3D
00742     (xx*b.xx+xy*b.yx+xz*b.zx, xx*b.xy+xy*b.yy+xz*b.zy,
00743      xx*b.xz+xy*b.yz+xz*b.zz, xx*b.dx+xy*b.dy+xz*b.dz+dx,
00744      yx*b.xx+yy*b.yx+yz*b.zx, yx*b.xy+yy*b.yy+yz*b.zy,
00745      yx*b.xz+yy*b.yz+yz*b.zz, yx*b.dx+yy*b.dy+yz*b.dz+dy,
00746      zx*b.xx+zy*b.yx+zz*b.zx, zx*b.xy+zy*b.yy+zz*b.zy,
00747      zx*b.xz+zy*b.yz+zz*b.zz, zx*b.dx+zy*b.dy+zz*b.dz+dz);
00748 }
00749 
00750 inline
00751 HepPoint3D HepTransform3D::operator*(const HepPoint3D &p) const {
00752   double x = p.x(), y = p.y(), z = p.z(); 
00753   return HepPoint3D(x*xx+y*xy+z*xz+dx, x*yx+y*yy+z*yz+dy, x*zx+y*zy+z*zz+dz);
00754 }
00755 
00756 inline
00757 HepVector3D HepTransform3D::operator*(const HepVector3D &v) const {
00758   double x = v.x(), y = v.y(), z = v.z(); 
00759   return HepPoint3D(x*xx+y*xy+z*xz, x*yx+y*yy+z*yz, x*zx+y*zy+z*zz);
00760 }
00761 
00762 inline
00763 HepNormal3D HepTransform3D::operator*(const HepNormal3D &n) const {
00764   double x = n.x(), y = n.y(), z = n.z(); 
00765   return HepNormal3D(x*(yy*zz-yz*zy) + y*(yz*zx-yx*zz) + z*(yx*zy-yy*zx),
00766                      x*(zy*xz-zz*xy) + y*(zz*xx-zx*xz) + z*(zx*xy-zy*xx),
00767                      x*(xy*yz-xz*yy) + y*(xz*yx-xx*yz) + z*(xx*yy-xy*yx));
00768 }
00769 
00770 inline
00771 HepRotation HepTransform3D::getRotation() const {
00772   HepRotation m;
00773   return m.rotateAxes(Hep3Vector(xx,yx,zx),
00774                       Hep3Vector(xy,yy,zy),
00775                       Hep3Vector(xz,yz,zz));
00776 }
00777 
00778 inline
00779 Hep3Vector HepTransform3D::getTranslation() const {
00780   return Hep3Vector(dx,dy,dz); 
00781 }
00782 
00783 //   I N L I N E S   F O R   R O T A T I O N
00784 
00785 inline HepRotate3D::HepRotate3D(const HepRotation &m) {
00786   Hep3Vector w;
00787   w = m * Hep3Vector(1,0,0); xx = w.x(); yx = w.y(); zx = w.z();
00788   w = m * Hep3Vector(0,1,0); xy = w.x(); yy = w.y(); zy = w.z();
00789   w = m * Hep3Vector(0,0,1); xz = w.x(); yz = w.y(); zz = w.z();
00790   dx = 0; dy = 0; dz = 0;
00791 }
00792 
00793 inline HepRotate3D::HepRotate3D(double a, const HepVector3D &v) {
00794   *this = HepRotate3D(a, HepPoint3D(0,0,0), HepPoint3D(v.x(),v.y(),v.z()));
00795 }
00796 
00797 inline HepRotate3D::HepRotate3D(const HepPoint3D &fr1, const HepPoint3D &fr2,
00798                                 const HepPoint3D &to1, const HepPoint3D &to2)
00799   : HepTransform3D(HepPoint3D(0,0,0),fr1,fr2, HepPoint3D(0,0,0),to1,to2) {}
00800 
00801 //   I N L I N E S   F O R   T R A N S L A T I O N
00802 
00803 inline HepTranslate3D::HepTranslate3D(const Hep3Vector &v)
00804   : HepTransform3D(1,0,0,v.x(), 0,1,0,v.y(), 0,0,1,v.z()) {}
00805 
00806 //   I N L I N E S   F O R   R E F L E C T I O N
00807 
00808 inline HepReflect3D::HepReflect3D(const HepNormal3D &n, const HepPoint3D &p) {
00809   *this = HepReflect3D(n.x(), n.y(), n.z(), -n*p);
00810 }
00811 
00812 #endif /* HEP_TRANSFROM3D_H */

Class Library for High Energy Physics (version 1.8)