00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef BLCOORDINATETRANSFORM_HH
00020 #define BLCOORDINATETRANSFORM_HH
00021
00022 #include <stdio.h>
00023
00024 #include "G4ThreeVector.hh"
00025 #include "G4RotationMatrix.hh"
00026
00027 #define DUMPROTATION(rot,str) \
00028 { G4ThreeVector x(1.0,0.0,0.0), z(0.0,0.0,1.0); \
00029 G4ThreeVector rx = rot * x; \
00030 G4ThreeVector rz = rot * z; \
00031 printf("%s: %.3f,%.3f,%.3f / %.3f,%.3f,%.3f / %.3f,%.3f,%.3f\n", \
00032 str,rot.xx(),rot.xy(),rot.xz(),rot.yx(),rot.yy(),rot.yz(), \
00033 rot.zx(),rot.zy(),rot.zz()); \
00034 printf(" rot*x=%.3f,%.3f,%.3f rot*z = %.3f,%.3f,%.3f\n", \
00035 rx[0],rx[1],rx[2],rz[0],rz[1],rz[2]); \
00036 }
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 class BLCoordinateTransform {
00050 G4RotationMatrix rot_p2l;
00051 G4RotationMatrix rot_l2p;
00052 G4ThreeVector position;
00053 G4bool rotated;
00054 void checkRotation() {
00055
00056 G4ThreeVector x(1.0,0.0,0.0), y(0.0,1.0,0.0);
00057 x = rot_p2l * x;
00058 y = rot_p2l * y;
00059 if(fabs(y[0]) > 1e-8 || fabs(y[1]-1.0) > 1e-8 ||
00060 fabs(y[2]) > 1e-8 || fabs(x[0]-1.0) > 1e-8 ||
00061 fabs(x[1]) > 1e-8 || fabs(x[2]) > 1e-8)
00062 rotated = true;
00063 else
00064 rotated = false;
00065 }
00066 public:
00067
00068 BLCoordinateTransform() : rot_p2l(), rot_l2p(), position(),
00069 rotated(false) { }
00070
00071
00072
00073 BLCoordinateTransform(const G4ThreeVector& pos) : rot_p2l(),
00074 rot_l2p(), position(pos), rotated(false) { }
00075
00076
00077 BLCoordinateTransform(const G4RotationMatrix &rot,
00078 const G4ThreeVector &pos) :
00079 rot_p2l(rot), rot_l2p(rot),
00080 position(pos), rotated(false)
00081 { rot_p2l.invert(); checkRotation(); }
00082
00083
00084 BLCoordinateTransform(const G4RotationMatrix *rot,
00085 const G4ThreeVector &pos) :
00086 rot_p2l(), rot_l2p(),
00087 position(pos), rotated(false)
00088 { if(rot) rot_p2l = rot_l2p = *rot; rot_p2l.invert();
00089 checkRotation(); }
00090
00091
00092
00093
00094
00095
00096
00097 void getLocal(G4double local[4], const G4double global[4]) const {
00098 G4ThreeVector l, g;
00099 g[0] = global[0];
00100 g[1] = global[1];
00101 g[2] = global[2];
00102 getLocal(l,g);
00103 local[0] = l[0];
00104 local[1] = l[1];
00105 local[2] = l[2];
00106 local[3] = global[3];
00107 }
00108
00109
00110
00111
00112
00113
00114 void getLocal(G4ThreeVector& local, const G4ThreeVector& global) const
00115 {
00116 if(rotated)
00117 local = rot_p2l * (global - position);
00118 else
00119 local = global - position;
00120 }
00121
00122
00123
00124
00125
00126
00127
00128 void getGlobal(const G4double local[4], G4double global[4]) const {
00129 G4ThreeVector l, g;
00130 l[0] = local[0];
00131 l[1] = local[1];
00132 l[2] = local[2];
00133 getGlobal(l,g);
00134 global[0] = g[0];
00135 global[1] = g[1];
00136 global[2] = g[2];
00137 global[3] = local[3];
00138 }
00139
00140
00141
00142
00143
00144
00145 void getGlobal(const G4ThreeVector& local, G4ThreeVector& global) const
00146 {
00147 if(rotated)
00148 global = rot_l2p * local + position;
00149 else
00150 global = local + position;
00151 }
00152
00153
00154
00155
00156
00157
00158
00159 void apply(const BLCoordinateTransform& parentTransform) {
00160 if(parentTransform.rotated) {
00161 position = parentTransform.rot_l2p * position +
00162 parentTransform.position;
00163 if(rotated)
00164 rot_p2l = rot_p2l * parentTransform.rot_p2l;
00165 else
00166 rot_p2l = parentTransform.rot_p2l;
00167 rot_l2p = rot_p2l;
00168 rot_l2p.invert();
00169 } else {
00170 position += parentTransform.position;
00171 }
00172 checkRotation();
00173 }
00174
00175
00176 G4ThreeVector& getPosition() { return position; }
00177
00178
00179 G4RotationMatrix& getRotation() { return rot_p2l; }
00180
00181
00182
00183
00184 G4RotationMatrix& getRotationInverse() { return rot_l2p; }
00185
00186
00187 G4bool isRotated() const { return rotated; }
00188 };
00189
00190 #endif // BLCOORDINATETRANSFORM_HH