![]() |
|
|||
File indexing completed on 2025-09-18 09:24:49
0001 //------------------------------- -*- C++ -*- -------------------------------// 0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details 0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT) 0004 //---------------------------------------------------------------------------// 0005 //! \file orange/g4org/Transformer.hh 0006 //---------------------------------------------------------------------------// 0007 #pragma once 0008 0009 #include <G4AffineTransform.hh> 0010 #include <G4RotationMatrix.hh> 0011 #include <G4ThreeVector.hh> 0012 0013 #include "orange/transform/VariantTransform.hh" 0014 0015 #include "Scaler.hh" 0016 0017 namespace celeritas 0018 { 0019 namespace g4org 0020 { 0021 //---------------------------------------------------------------------------// 0022 /*! 0023 * Return an ORANGE transformation from a Geant4 transformation. 0024 * 0025 * In Geant4, "object" or "direct" transform refers to daughter-to-parent, how 0026 * to place the daughter object in the parent. The "frame" transform (raw \c 0027 * GetTransform or the \c fPtrTransform object) is how to transform from parent 0028 * to daughter and is the inverse of that transform. 0029 * 0030 * Even though the affine transform's matrix has a \c operator() which does a 0031 * matrix-vector multiply (aka \c gemv), this is *not* the same as the affine 0032 * transform's rotation, which applies the *inverse* of the stored matrix. 0033 * 0034 * All ORANGE/Celeritas transforms are "daughter to parent". The transforms 0035 * returned from this function \em must be daughter-to-parent! 0036 */ 0037 class Transformer 0038 { 0039 public: 0040 //!@{ 0041 //! \name Type aliases 0042 using Real3 = Array<double, 3>; 0043 //!@} 0044 0045 public: 0046 // Construct with a scale 0047 inline explicit Transformer(Scaler const& scale); 0048 0049 // Convert a translation 0050 inline Translation operator()(G4ThreeVector const& t) const; 0051 0052 // Convert a pure rotation 0053 inline Transformation operator()(G4RotationMatrix const& rot) const; 0054 0055 // Convert a translation + rotation 0056 inline Transformation 0057 operator()(G4ThreeVector const& t, G4RotationMatrix const& rot) const; 0058 0059 // Convert a translation + optional rotation 0060 inline VariantTransform 0061 operator()(G4ThreeVector const& t, G4RotationMatrix const* rot) const; 0062 0063 // Convert an affine transform 0064 inline Transformation operator()(G4AffineTransform const& at) const; 0065 0066 private: 0067 //// DATA //// 0068 0069 Scaler const& scale_; 0070 }; 0071 0072 //---------------------------------------------------------------------------// 0073 // FREE FUNCTIONS 0074 //---------------------------------------------------------------------------// 0075 // Convert a rotation matrix 0076 inline SquareMatrixReal3 convert_from_geant(G4RotationMatrix const& rot); 0077 0078 //---------------------------------------------------------------------------// 0079 // Get the transpose/inverse of a rotation matrix 0080 inline SquareMatrixReal3 transposed_from_geant(G4RotationMatrix const& rot); 0081 0082 //---------------------------------------------------------------------------// 0083 // INLINE DEFINITIONS 0084 //---------------------------------------------------------------------------// 0085 /*! 0086 * Construct with a scaling function. 0087 */ 0088 Transformer::Transformer(Scaler const& scale) : scale_{scale} {} 0089 0090 //---------------------------------------------------------------------------// 0091 /*! 0092 * Create a transform from a translation. 0093 */ 0094 auto Transformer::operator()(G4ThreeVector const& t) const -> Translation 0095 { 0096 return Translation{scale_.to<Real3>(t[0], t[1], t[2])}; 0097 } 0098 0099 //---------------------------------------------------------------------------// 0100 /*! 0101 * Create a transform from a translation plus rotation. 0102 */ 0103 auto Transformer::operator()(G4ThreeVector const& trans, 0104 G4RotationMatrix const& rot) const -> Transformation 0105 { 0106 return Transformation{convert_from_geant(rot), scale_.to<Real3>(trans)}; 0107 } 0108 0109 //---------------------------------------------------------------------------// 0110 /*! 0111 * Create a transform from an affine transform. 0112 * 0113 * The affine transform's stored rotation matrix is \em inverted! 0114 */ 0115 auto Transformer::operator()(G4AffineTransform const& affine) const 0116 -> Transformation 0117 { 0118 return Transformation{transposed_from_geant(affine.NetRotation()), 0119 scale_.to<Real3>(affine.NetTranslation())}; 0120 } 0121 0122 //---------------------------------------------------------------------------// 0123 /*! 0124 * Convert a rotation matrix. 0125 */ 0126 SquareMatrixReal3 convert_from_geant(G4RotationMatrix const& rot) 0127 { 0128 return {Real3{{rot.xx(), rot.xy(), rot.xz()}}, 0129 Real3{{rot.yx(), rot.yy(), rot.yz()}}, 0130 Real3{{rot.zx(), rot.zy(), rot.zz()}}}; 0131 } 0132 0133 //---------------------------------------------------------------------------// 0134 /*! 0135 * Get a transposed rotation matrix. 0136 */ 0137 SquareMatrixReal3 transposed_from_geant(G4RotationMatrix const& rot) 0138 { 0139 return {Real3{{rot.xx(), rot.yx(), rot.zx()}}, 0140 Real3{{rot.xy(), rot.yy(), rot.zy()}}, 0141 Real3{{rot.xz(), rot.yz(), rot.zz()}}}; 0142 } 0143 0144 //---------------------------------------------------------------------------// 0145 } // namespace g4org 0146 } // namespace celeritas
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |