Geant4 Cross Reference |
1 // -*- C++ -*- 1 2 // ------------------------------------------- 3 // 4 // This file is a part of the CLHEP - a Class 5 // 6 // Hep geometrical 3D Transformation class 7 // 8 // Author: Evgeni Chernyaev <Evgueni.Tcherniae 9 // 10 // ********************************** 11 // * 12 // * Transform 13 // * / / \ \ 14 // * -------- / \ -------- 15 // * / / \ \ 16 // * Rotate Translate Reflect Sc 17 // * / | \ / | \ / | \ / 18 // * X Y Z X Y Z X Y Z X 19 // * 20 // ********************************** 21 // 22 // Identity transformation: 23 // Transform3D::Identity - global identity 24 // any constructor without parameters, e.g. 25 // m.setIdentity() - set "m" to i 26 // 27 // General transformations: 28 // Transform3D(m,v) - transformation 29 // and CLHEP::Hep 30 // Transform3D(a0,a1,a2, b0,b1,b2) - transfo 31 // and transform 32 // Rotations: 33 // Rotate3D(m) - rotation given 34 // Rotate3D(ang,v) - rotation throu 35 // vector "v"; 36 // Rotate3D(ang,p1,p2) - rotation throu 37 // counterclockwi 38 // two points p1- 39 // Rotate3D(a1,a2, b1,b2) - rotation aroun 40 // and transforme 41 // RotateX3D(ang) - rotation aroun 42 // RotateY3D(ang) - rotation aroun 43 // RotateZ3D(ang) - rotation aroun 44 // 45 // Translations: 46 // Translate3D(v) - translation gi 47 // Translate3D(dx,dy,dz) - translation on 48 // TraslateX3D(dx) - translation al 49 // TraslateY3D(dy) - translation al 50 // TraslateZ3D(dz) - translation al 51 // 52 // Reflections: 53 // Reflect3D(a,b,c,d) - reflection in 54 // Reflect3D(normal,p) - reflection in 55 // and whose norm 56 // ReflectX3D(a) - reflect X in t 57 // ReflectY3D(a) - reflect Y in t 58 // ReflectZ3D(a) - reflect Z in t 59 // 60 // Scalings: 61 // Scale3D(sx,sy,sz) - general scalin 62 // along X, Y 63 // Scale3D(s) - scaling with c 64 // directions; 65 // ScaleX3D(sx) - scale X; 66 // ScaleY3D(sy) - scale Y; 67 // ScaleZ3D(sz) - scale Z; 68 // 69 // Inverse transformation: 70 // m.inverse() or - returns invers 71 // 72 // Compound transformation: 73 // m3 = m2 * m1 - it is relative 74 // transformation 75 // to avoid this 76 // Transformation of point: 77 // p2 = m * p1 78 // 79 // Transformation of vector: 80 // v2 = m * v1 81 // 82 // Transformation of normal: 83 // n2 = m * n1 84 // 85 // The following table explains how different 86 // point, vector and normal. "+" means affect, 87 // "*" meas affect but in different way than " 88 // 89 // Point Vector Normal 90 // -------------+-------+-------+------- 91 // Rotation ! + ! + ! + 92 // Translation ! + ! - ! - 93 // Reflection ! + ! + ! * 94 // Scaling ! + ! + ! * 95 // -------------+-------+-------+------- 96 // 97 // Example of the usage: 98 // 99 // Transform3D m1, m2, m3; 100 // HepVector3D v2, v1(0,0,0); 101 // 102 // m1 = Rotate3D(angle, Vector3D(1,1,1)); 103 // m2 = Translate3D(dx,dy,dz); 104 // m3 = m1.inverse(); 105 // 106 // v2 = m3*(m2*(m1*v1)); 107 // 108 // History: 109 // 24.09.96 E.Chernyaev - initial version 110 // 111 // 26.02.97 E.Chernyaev 112 // - added global Identity by request of John 113 // (to avoid problems with compilation on HP 114 // - added getRotation and getTranslation 115 // 116 // 29.01.01 E.Chernyaev - added subscripting 117 // 11.06.01 E.Chernyaev - added getDecompositi 118 119 #ifndef HEP_TRANSFROM3D_H 120 #define HEP_TRANSFROM3D_H 121 122 #include "CLHEP/Vector/ThreeVector.h" 123 124 namespace HepGeom { 125 126 template<class T> class Point3D; 127 template<class T> class Vector3D; 128 template<class T> class Normal3D; 129 130 class Translate3D; 131 class Rotate3D; 132 class Scale3D; 133 134 /** 135 * Class for transformation of 3D geometrica 136 * It allows different translations, rotatio 137 * Several specialized classes are derived f 138 * 139 * TranslateX3D, TranslateY3D, TranslateZ3D, 140 * RotateX3D, RotateY3D, RotateZ3D, 141 * ScaleX3D, ScaleY3D, ScaleZ3D, 142 * ReflectX3D, ReflectY3D, ReflectZ3D, 143 * 144 * The idea behind these classes is to provi 145 * for Transform3D, they normally should not 146 * 147 * Example: 148 * @code 149 * HepGeom::Transform3D m; 150 * m = HepGeom::TranslateX3D(10.*cm); 151 * @endcode 152 * 153 * Remark: 154 * For the reason that the operator* is left 155 * @code 156 * v2 = m3*(m2*(m1*v1)); 157 * @endcode 158 * is much more effective then the notation 159 * @code 160 * v2 = m3*m2*m1*v1; 161 * @endcode 162 * In the first case three operations Transf 163 * in the second case two operations Transfo 164 * Transform3D*Vector3D are performed. Trans 165 * roughly three times slower than Transform 166 * 167 * @author <Evgueni.Tcherniaev@cern.ch> 168 * @ingroup geometry 169 */ 170 class Transform3D { 171 protected: 172 double xx_, xy_, xz_, dx_, // 4x3 Tra 173 yx_, yy_, yz_, dy_, 174 zx_, zy_, zz_, dz_; 175 176 // Protected constructor 177 Transform3D(double XX, double XY, double X 178 double YX, double YY, double YZ, double DY 179 double ZX, double ZY, double ZZ, double DZ 180 : xx_(XX), xy_(XY), xz_(XZ), dx_(DX), 181 yx_(YX), yy_(YY), yz_(YZ), dy_(DY), 182 zx_(ZX), zy_(ZY), zz_(ZZ), dz_(DZ) {} 183 184 // Set transformation matrix 185 void setTransform(double XX, double XY, do 186 double YX, double YY, double YZ, dou 187 double ZX, double ZY, double ZZ, dou 188 xx_ = XX; xy_ = XY; xz_ = XZ; dx_ = DX; 189 yx_ = YX; yy_ = YY; yz_ = YZ; dy_ = DY; 190 zx_ = ZX; zy_ = ZY; zz_ = ZZ; dz_ = DZ; 191 } 192 193 public: 194 /** 195 * Global identity transformation. */ 196 DLL_API static const Transform3D Identity; 197 198 // Helper class for implemention of C-styl 199 class Transform3D_row { 200 public: 201 inline Transform3D_row(const Transform3D 202 inline double operator [] (int) const; 203 private: 204 const Transform3D & rr; 205 int ii; 206 }; 207 208 /** 209 * Default constructor - sets the Identity 210 Transform3D() 211 : xx_(1), xy_(0), xz_(0), dx_(0), 212 yx_(0), yy_(1), yz_(0), dy_(0), 213 zx_(0), zy_(0), zz_(1), dz_(0) {} 214 215 /** 216 * Constructor: rotation and then translat 217 inline Transform3D(const CLHEP::HepRotatio 218 219 /** 220 * Constructor: transformation of basis (a 221 Transform3D(const Point3D<double> & fr0, 222 const Point3D<double> & fr1, 223 const Point3D<double> & fr2, 224 const Point3D<double> & to0, 225 const Point3D<double> & to1, 226 const Point3D<double> & to2); 227 228 /** 229 * Copy constructor. */ 230 Transform3D(const Transform3D & mt) = defa 231 232 /** 233 * Move constructor. */ 234 Transform3D(Transform3D && mt) = default; 235 236 /** 237 * Destructor. */ 238 ~Transform3D() = default; 239 240 /** 241 * Assignment. */ 242 Transform3D & operator=(const Transform3D 243 244 /** 245 * Move assignment. */ 246 Transform3D & operator=(Transform3D && mt) 247 248 /** 249 * Returns object of the helper class for 250 inline const Transform3D_row operator [] ( 251 252 /** Fortran-style subscripting: returns (i 253 double operator () (int, int) const; 254 255 /** 256 * Gets xx-element of the transformation m 257 double xx() const { return xx_; } 258 /** 259 * Gets xy-element of the transformation m 260 double xy() const { return xy_; } 261 /** 262 * Gets xz-element of the transformation m 263 double xz() const { return xz_; } 264 /** 265 * Gets yx-element of the transformation m 266 double yx() const { return yx_; } 267 /** 268 * Gets yy-element of the transformation m 269 double yy() const { return yy_; } 270 /** 271 * Gets yz-element of the transformation m 272 double yz() const { return yz_; } 273 /** 274 * Gets zx-element of the transformation m 275 double zx() const { return zx_; } 276 /** 277 * Gets zy-element of the transformation m 278 double zy() const { return zy_; } 279 /** 280 * Gets zz-element of the transformation m 281 double zz() const { return zz_; } 282 /** 283 * Gets dx-element of the transformation m 284 double dx() const { return dx_; } 285 /** 286 * Gets dy-element of the transformation m 287 double dy() const { return dy_; } 288 /** 289 * Gets dz-element of the transformation m 290 double dz() const { return dz_; } 291 292 /** 293 * Sets the Identity transformation. */ 294 void setIdentity() { 295 xy_= xz_= dx_= yx_= yz_= dy_= zx_= zy_= 296 } 297 298 /** 299 * Returns the inverse transformation. */ 300 Transform3D inverse() const; 301 302 /** 303 * Transformation by another Transform3D. 304 Transform3D operator*(const Transform3D & 305 306 /** 307 * Decomposition of general transformation 308 * This function gets decomposition of the 309 * in three consequentive specific transfo 310 * then Rotate3D, then Translate3, i.e. 311 * @code 312 * Transform3D = Translate3D * Rotate3D 313 * @endcode 314 * 315 * @param scale output: scaling tran 316 * if there was a refle 317 * z-component (scale(2 318 * @param rotation output: rotation tra 319 * @param translation output: translation 320 */ 321 void getDecomposition(Scale3D & scale, 322 Rotate3D & rotation, 323 Translate3D & translation) const; 324 325 /** 326 * Returns true if the difference between 327 * matrix elements is less than the tolera 328 */ 329 bool isNear(const Transform3D & t, double 330 331 /** 332 * Extracts the rotation matrix. 333 * This functions is obsolete - use getDec 334 */ 335 inline CLHEP::HepRotation getRotation() co 336 337 /** 338 * Extracts the translation vector. 339 * This functions is obsolete - use getDec 340 */ 341 inline CLHEP::Hep3Vector getTranslation() 342 343 /** 344 * Test for equality. */ 345 bool operator == (const Transform3D & tran 346 347 /** 348 * Test for inequality. */ 349 bool operator != (const Transform3D & tran 350 return ! operator==(transform); 351 } 352 }; 353 354 // R O T A T I O N S 355 356 /** 357 * Constructs a rotation transformation. 358 * This class provides additional constructo 359 * and should not be used as a separate clas 360 * 361 * Example of use: 362 * @code 363 * Transform3D m; 364 * m = Rotate3D(30.*deg, HepVector3D(1.,1. 365 * @endcode 366 * 367 * @author <Evgueni.Tcherniaev@cern.ch> 368 * @ingroup geometry 369 */ 370 class Rotate3D : public Transform3D { 371 public: 372 /** 373 * Default constructor: sets the Identity 374 Rotate3D() : Transform3D() {} 375 376 /** 377 * Constructor from CLHEP::HepRotation. */ 378 inline Rotate3D(const CLHEP::HepRotation & 379 380 /** 381 * Constructor from angle and axis given b 382 * @param a angle of rotation 383 * @param p1 begin point of the axis 384 * @param p2 end point of the axis 385 */ 386 Rotate3D(double a, 387 const Point3D<double> & p1, 388 const Point3D<double> & p2); 389 390 /** 391 * Constructor from angle and axis. 392 * @param a angle of rotation 393 * @param v axis of rotation 394 */ 395 inline Rotate3D(double a, const Vector3D<d 396 397 /** 398 * Constructor for rotation given by origi 399 * two points. It is assumed that there is 400 * @param fr1 original position of 1st poi 401 * @param fr2 original position of 2nd poi 402 * @param to1 rotated position of 1st poin 403 * @param to2 rotated position of 2nd poin 404 */ 405 inline Rotate3D(const Point3D<double> & fr 406 const Point3D<double> & fr2, 407 const Point3D<double> & to1, 408 const Point3D<double> & to2); 409 }; 410 411 /** 412 * Constructs a rotation around x-axis. 413 * This class provides additional constructo 414 * and should not be used as a separate clas 415 * 416 * Example of use: 417 * @code 418 * Transform3D m; 419 * m = RotateX3D(30.*deg); 420 * @endcode 421 * 422 * @author <Evgueni.Tcherniaev@cern.ch> 423 * @ingroup geometry 424 */ 425 class RotateX3D : public Rotate3D { 426 public: 427 /** 428 * Default constructor: sets the Identity 429 RotateX3D() : Rotate3D() {} 430 431 /** 432 * Constructs a rotation around x-axis by 433 RotateX3D(double a) { 434 double cosa = std::cos(a), sina = std::s 435 setTransform(1,0,0,0, 0,cosa,-sina,0, 436 } 437 }; 438 439 /** 440 * Constructs a rotation around y-axis. 441 * This class provides additional constructo 442 * and should not be used as a separate clas 443 * 444 * Example of use: 445 * @code 446 * Transform3D m; 447 * m = RotateY3D(30.*deg); 448 * @endcode 449 * 450 * @author <Evgueni.Tcherniaev@cern.ch> 451 * @ingroup geometry 452 */ 453 class RotateY3D : public Rotate3D { 454 public: 455 /** 456 * Default constructor: sets the Identity 457 RotateY3D() : Rotate3D() {} 458 459 /** 460 * Constructs a rotation around y-axis by 461 RotateY3D(double a) { 462 double cosa = std::cos(a), sina = std::s 463 setTransform(cosa,0,sina,0, 0,1,0,0, - 464 } 465 }; 466 467 /** 468 * Constructs a rotation around z-axis. 469 * This class provides additional constructo 470 * and should not be used as a separate clas 471 * 472 * Example of use: 473 * @code 474 * Transform3D m; 475 * m = RotateZ3D(30.*deg); 476 * @endcode 477 * 478 * @author <Evgueni.Tcherniaev@cern.ch> 479 * @ingroup geometry 480 */ 481 class RotateZ3D : public Rotate3D { 482 public: 483 /** 484 * Default constructor: sets the Identity 485 RotateZ3D() : Rotate3D() {} 486 487 /** 488 * Constructs a rotation around z-axis by 489 RotateZ3D(double a) { 490 double cosa = std::cos(a), sina = std::s 491 setTransform(cosa,-sina,0,0, sina,cosa, 492 } 493 }; 494 495 // T R A N S L A T I O N S 496 497 /** 498 * Constructs a translation transformation. 499 * This class provides additional constructo 500 * and should not be used as a separate clas 501 * 502 * Example of use: 503 * @code 504 * Transform3D m; 505 * m = Translate3D(10.,20.,30.); 506 * @endcode 507 * 508 * @author <Evgueni.Tcherniaev@cern.ch> 509 * @ingroup geometry 510 */ 511 class Translate3D : public Transform3D { 512 public: 513 /** 514 * Default constructor: sets the Identity 515 Translate3D() : Transform3D() {} 516 517 /** 518 * Constructor from CLHEP::Hep3Vector. */ 519 inline Translate3D(const CLHEP::Hep3Vector 520 521 /** 522 * Constructor from three numbers. */ 523 Translate3D(double x, double y, double z) 524 : Transform3D(1,0,0,x, 0,1,0,y, 0,0,1,z) 525 }; 526 527 /** 528 * Constructs a translation along x-axis. 529 * This class provides additional constructo 530 * and should not be used as a separate clas 531 * 532 * Example of use: 533 * @code 534 * Transform3D m; 535 * m = TranslateX3D(10.); 536 * @endcode 537 * 538 * @author <Evgueni.Tcherniaev@cern.ch> 539 * @ingroup geometry 540 */ 541 class TranslateX3D : public Translate3D { 542 public: 543 /** 544 * Default constructor: sets the Identity 545 TranslateX3D() : Translate3D() {} 546 547 /** 548 * Constructor from a number. */ 549 TranslateX3D(double x) : Translate3D(x, 0, 550 }; 551 552 /** 553 * Constructs a translation along y-axis. 554 * This class provides additional constructo 555 * and should not be used as a separate clas 556 * 557 * Example of use: 558 * @code 559 * Transform3D m; 560 * m = TranslateY3D(10.); 561 * @endcode 562 * 563 * @author <Evgueni.Tcherniaev@cern.ch> 564 * @ingroup geometry 565 */ 566 class TranslateY3D : public Translate3D { 567 public: 568 /** 569 * Default constructor: sets the Identity 570 TranslateY3D() : Translate3D() {} 571 572 /** 573 * Constructor from a number. */ 574 TranslateY3D(double y) : Translate3D(0, y, 575 }; 576 577 /** 578 * Constructs a translation along z-axis. 579 * This class provides additional constructo 580 * and should not be used as a separate clas 581 * 582 * Example of use: 583 * @code 584 * Transform3D m; 585 * m = TranslateZ3D(10.); 586 * @endcode 587 * 588 * @author <Evgueni.Tcherniaev@cern.ch> 589 * @ingroup geometry 590 */ 591 class TranslateZ3D : public Translate3D { 592 public: 593 /** 594 * Default constructor: sets the Identity 595 TranslateZ3D() : Translate3D() {} 596 597 /** 598 * Constructor from a number. */ 599 TranslateZ3D(double z) : Translate3D(0, 0, 600 }; 601 602 // R E F L E C T I O N S 603 604 /** 605 * Constructs a reflection transformation. 606 * This class provides additional constructo 607 * and should not be used as a separate clas 608 * 609 * Example of use: 610 * @code 611 * Transform3D m; 612 * m = Reflect3D(1.,1.,1.,0.); 613 * @endcode 614 * 615 * @author <Evgueni.Tcherniaev@cern.ch> 616 * @ingroup geometry 617 */ 618 class Reflect3D : public Transform3D { 619 protected: 620 Reflect3D(double XX, double XY, double XZ, 621 double YX, double YY, double YZ, 622 double ZX, double ZY, double ZZ, 623 : Transform3D(XX,XY,XZ,DX, YX,YY,YZ,DY, 624 625 public: 626 /** 627 * Default constructor: sets the Identity 628 Reflect3D() : Transform3D() {} 629 630 /** 631 * Constructor from four numbers. 632 * Sets reflection in a plane a*x+b*y+c*z+ 633 */ 634 Reflect3D(double a, double b, double c, do 635 636 /** 637 * Constructor from a plane given by its n 638 inline Reflect3D(const Normal3D<double> & 639 const Point3D<double> & p 640 }; 641 642 /** 643 * Constructs reflection in a plane x=const. 644 * This class provides additional constructo 645 * and should not be used as a separate clas 646 * 647 * Example of use: 648 * @code 649 * Transform3D m; 650 * m = ReflectX3D(1.); 651 * @endcode 652 * 653 * @author <Evgueni.Tcherniaev@cern.ch> 654 * @ingroup geometry 655 */ 656 class ReflectX3D : public Reflect3D { 657 public: 658 /** 659 * Constructor from a number. */ 660 ReflectX3D(double x=0) : Reflect3D(-1,0,0, 661 }; 662 663 /** 664 * Constructs reflection in a plane y=const. 665 * This class provides additional constructo 666 * and should not be used as a separate clas 667 * 668 * Example of use: 669 * @code 670 * Transform3D m; 671 * m = ReflectY3D(1.); 672 * @endcode 673 * 674 * @author <Evgueni.Tcherniaev@cern.ch> 675 * @ingroup geometry 676 */ 677 class ReflectY3D : public Reflect3D { 678 public: 679 /** 680 * Constructor from a number. */ 681 ReflectY3D(double y=0) : Reflect3D(1,0,0,0 682 }; 683 684 /** 685 * Constructs reflection in a plane z=const. 686 * This class provides additional constructo 687 * and should not be used as a separate clas 688 * 689 * Example of use: 690 * @code 691 * Transform3D m; 692 * m = ReflectZ3D(1.); 693 * @endcode 694 * 695 * @author <Evgueni.Tcherniaev@cern.ch> 696 * @ingroup geometry 697 */ 698 class ReflectZ3D : public Reflect3D { 699 public: 700 /** 701 * Constructor from a number. */ 702 ReflectZ3D(double z=0) : Reflect3D(1,0,0,0 703 }; 704 705 // S C A L I N G S 706 707 /** 708 * Constructs a scaling transformation. 709 * This class provides additional constructo 710 * and should not be used as a separate clas 711 * 712 * Example of use: 713 * @code 714 * Transform3D m; 715 * m = Scale3D(2.); 716 * @endcode 717 * 718 * @author <Evgueni.Tcherniaev@cern.ch> 719 * @ingroup geometry 720 */ 721 class Scale3D : public Transform3D { 722 public: 723 /** 724 * Default constructor: sets the Identity 725 Scale3D() : Transform3D() {} 726 727 /** 728 * Constructor from three numbers - scale 729 */ 730 Scale3D(double x, double y, double z) 731 : Transform3D(x,0,0,0, 0,y,0,0, 0,0,z,0) 732 733 /** 734 * Constructor from a number: sets uniform 735 Scale3D(double sc) 736 : Transform3D(sc,0,0,0, 0,sc,0,0, 0,0,sc 737 }; 738 739 /** 740 * Constructs a scaling transformation in x- 741 * This class provides additional constructo 742 * and should not be used as a separate clas 743 * 744 * Example of use: 745 * @code 746 * Transform3D m; 747 * m = ScaleX3D(2.); 748 * @endcode 749 * 750 * @author <Evgueni.Tcherniaev@cern.ch> 751 * @ingroup geometry 752 */ 753 class ScaleX3D : public Scale3D { 754 public: 755 /** 756 * Default constructor: sets the Identity 757 ScaleX3D() : Scale3D() {} 758 759 /** 760 * Constructor from a number (scale factor 761 ScaleX3D(double x) : Scale3D(x, 1, 1) {} 762 }; 763 764 /** 765 * Constructs a scaling transformation in y- 766 * This class provides additional constructo 767 * and should not be used as a separate clas 768 * 769 * Example of use: 770 * @code 771 * Transform3D m; 772 * m = ScaleY3D(2.); 773 * @endcode 774 * 775 * @author <Evgueni.Tcherniaev@cern.ch> 776 * @ingroup geometry 777 */ 778 class ScaleY3D : public Scale3D { 779 public: 780 /** 781 * Default constructor: sets the Identity 782 ScaleY3D() : Scale3D() {} 783 784 /** 785 * Constructor from a number (scale factor 786 ScaleY3D(double y) : Scale3D(1, y, 1) {} 787 }; 788 789 /** 790 * Constructs a scaling transformation in z- 791 * This class provides additional constructo 792 * and should not be used as a separate clas 793 * 794 * Example of use: 795 * @code 796 * Transform3D m; 797 * m = ScaleZ3D(2.); 798 * @endcode 799 * 800 * @author <Evgueni.Tcherniaev@cern.ch> 801 * @ingroup geometry 802 */ 803 class ScaleZ3D : public Scale3D { 804 public: 805 /** 806 * Default constructor: sets the Identity 807 ScaleZ3D() : Scale3D() {} 808 /** 809 * Constructor from a number (scale factor 810 ScaleZ3D(double z) : Scale3D(1, 1, z) {} 811 }; 812 } /* namespace HepGeom */ 813 814 #include "CLHEP/Geometry/Transform3D.icc" 815 816 #endif /* HEP_TRANSFROM3D_H */ 817