Geant4  10.00.p03
UTransform3D.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * This Software is part of the AIDA Unified Solids Library package *
4 // * See: https://aidasoft.web.cern.ch/USolids *
5 // ********************************************************************
6 //
7 // $Id:$
8 //
9 // --------------------------------------------------------------------
10 //
11 // UTransform3D
12 //
13 // 19.09.12 Marek Gayer
14 // Created from original implementation in CLHEP
15 // --------------------------------------------------------------------
16 
17 #include <cmath>
18 #include <cstring>
19 
20 #include "UTransform3D.hh"
21 #include "UUtils.hh"
22 
23 const static double kIdRot[9] =
24 {
25  1.0, 0.0, 0.0,
26  0.0, 1.0, 0.0,
27  0.0, 0.0, 1.0
28 };
29 
30 //______________________________________________________________________________
32 {
33  // Dummy constructor
34  fTr.Set(0);
35  std::memcpy(fRot, kIdRot, sizeof(kIdRot));
36 }
37 
38 //______________________________________________________________________________
39 UTransform3D::UTransform3D(double tx, double ty, double tz,
40  double phi, double theta, double psi)
41 {
42  // Constructor providing a translation and Euler angles
43  // See description for SetAngles() method.
44  // This represent the composition of : first a rotation about Z axis with
45  // angle phi, then a rotation with theta about the rotated X axis, and
46  // finally a rotation with psi about the new Z axis.
47 
48  fTr.Set(tx, ty, tz);
49  SetAngles(phi, theta, psi);
50 }
51 
52 //______________________________________________________________________________
54 {
55  // Copy constructor.
56 
57  fTr = other.fTr;
58  std::memcpy(fRot, other.fRot, sizeof(kIdRot));
59 
60 }
61 
62 //______________________________________________________________________________
64 {
65  if (&other == this) return *this;
66  fTr = other.fTr;
67  std::memcpy(fRot, other.fRot, sizeof(kIdRot));
68  return *this;
69 }
70 
71 //______________________________________________________________________________
72 void UTransform3D::SetAngles(double phi, double theta, double psi)
73 {
74  // Set the rotation from Euler angles in the X-axis convention
75  // See: http://mathworld.wolfram.com/EulerAngles.html
76  // This represent the composition of : first a rotation about Z axis with
77  // angle phi, then a rotation with theta about the rotated X axis, and
78  // finally a rotation with psi about the new Z axis.
79 
80  // NOTE: angles are in degrees
81  double degrad = UUtils::kDegToRad;
82  double sinphi = std::sin(degrad * phi);
83  double cosphi = std::cos(degrad * phi);
84  double sinthe = std::sin(degrad * theta);
85  double costhe = std::cos(degrad * theta);
86  double sinpsi = std::sin(degrad * psi);
87  double cospsi = std::cos(degrad * psi);
88 
89  fRot[0] = cospsi * cosphi - costhe * sinphi * sinpsi;
90  fRot[1] = -sinpsi * cosphi - costhe * sinphi * cospsi;
91  fRot[2] = sinthe * sinphi;
92  fRot[3] = cospsi * sinphi + costhe * cosphi * sinpsi;
93  fRot[4] = -sinpsi * sinphi + costhe * cosphi * cospsi;
94  fRot[5] = -sinthe * cosphi;
95  fRot[6] = sinpsi * sinthe;
96  fRot[7] = cospsi * sinthe;
97  fRot[8] = costhe;
98 }
99 
100 //______________________________________________________________________________
101 void UTransform3D::RotateX(double angle)
102 {
103  // Rotate the transformation about the X axis with a given angle (in degrees).
104  double phi = angle * UUtils::kDegToRad;
105  double c = std::cos(phi);
106  double s = std::sin(phi);
107  double v[9];
108  v[0] = fRot[0];
109  v[1] = fRot[1];
110  v[2] = fRot[2];
111  v[3] = c * fRot[3] - s * fRot[6];
112  v[4] = c * fRot[4] - s * fRot[7];
113  v[5] = c * fRot[5] - s * fRot[8];
114  v[6] = s * fRot[3] + c * fRot[6];
115  v[7] = s * fRot[4] + c * fRot[7];
116  v[8] = s * fRot[5] + c * fRot[8];
117  std::memcpy(fRot, v, sizeof(kIdRot));
118 
119  fTr.Set(fTr.x, c * fTr.y - s * fTr.z, s * fTr.y + c * fTr.z);
120 }
121 
122 //______________________________________________________________________________
123 void UTransform3D::RotateY(double angle)
124 {
125  // Rotate the transformation about the Y axis with a given angle (in degrees).
126  double phi = angle * UUtils::kDegToRad;
127  double c = std::cos(phi);
128  double s = std::sin(phi);
129  double v[9];
130  v[0] = c * fRot[0] + s * fRot[6];
131  v[1] = c * fRot[1] + s * fRot[7];
132  v[2] = c * fRot[2] + s * fRot[8];
133  v[3] = fRot[3];
134  v[4] = fRot[4];
135  v[5] = fRot[5];
136  v[6] = -s * fRot[0] + c * fRot[6];
137  v[7] = -s * fRot[1] + c * fRot[7];
138  v[8] = -s * fRot[2] + c * fRot[8];
139  std::memcpy(fRot, v, sizeof(kIdRot));
140 
141  fTr.Set(c * fTr.x + s * fTr.z, fTr.y, -s * fTr.x + c * fTr.z);
142 }
143 
144 //______________________________________________________________________________
145 void UTransform3D::RotateZ(double angle)
146 {
147  // Rotate the transformation about the Z axis with a given angle (in degrees).
148  double phi = angle * UUtils::kDegToRad;
149  double c = std::cos(phi);
150  double s = std::sin(phi);
151  double v[9];
152  v[0] = c * fRot[0] - s * fRot[3];
153  v[1] = c * fRot[1] - s * fRot[4];
154  v[2] = c * fRot[2] - s * fRot[5];
155  v[3] = s * fRot[0] + c * fRot[3];
156  v[4] = s * fRot[1] + c * fRot[4];
157  v[5] = s * fRot[2] + c * fRot[5];
158  v[6] = fRot[6];
159  v[7] = fRot[7];
160  v[8] = fRot[8];
161  std::memcpy(&fRot[0], v, sizeof(kIdRot));
162 
163  fTr.Set(c * fTr.x - s * fTr.y, s * fTr.x + c * fTr.y, fTr.z);
164 }
165 
166 //______________________________________________________________________________
168 {
169  // Returns global point coordinates converted from the local frame defined
170  // by the transformation. This is defined by multiplying this transformation
171  // with the local vector.
172  UVector3 global;
173  global.x = fTr.x + local.x * fRot[0] + local.y * fRot[1] + local.z * fRot[2];
174  global.y = fTr.y + local.x * fRot[3] + local.y * fRot[4] + local.z * fRot[5];
175  global.z = fTr.z + local.x * fRot[6] + local.y * fRot[7] + local.z * fRot[8];
176  return global;
177 }
178 
179 //______________________________________________________________________________
181 {
182  // Returns vector components converted from the local frame defined by the
183  // transformation to the global one. This is defined by multiplying this
184  // transformation with the local vector while ignoring the translation.
185  UVector3 global(
186  local.x * fRot[0] + local.y * fRot[1] + local.z * fRot[2],
187  local.x * fRot[3] + local.y * fRot[4] + local.z * fRot[5],
188  local.x * fRot[6] + local.y * fRot[7] + local.z * fRot[8]);
189 
190  return global;
191 }
192 
193 //______________________________________________________________________________
195 {
196  // Returns local point coordinates converted from the global frame defined
197  // by the transformation. This is defined by multiplying the inverse
198  // transformation with the global vector.
199  UVector3 mt = global - fTr;
200  UVector3 local(
201  mt.x * fRot[0] + mt.y * fRot[3] + mt.z * fRot[6],
202  mt.x * fRot[1] + mt.y * fRot[4] + mt.z * fRot[7],
203  mt.x * fRot[2] + mt.y * fRot[5] + mt.z * fRot[8]);
204  return local;
205 }
206 
207 //______________________________________________________________________________
209 {
210  // Returns local point coordinates converted from the global frame defined
211  // by the transformation. This is defined by multiplying the inverse
212  // transformation with the global vector.
213  UVector3 local(
214  global.x * fRot[0] + global.y * fRot[3] + global.z * fRot[6],
215  global.x * fRot[1] + global.y * fRot[4] + global.z * fRot[7],
216  global.x * fRot[2] + global.y * fRot[5] + global.z * fRot[8]);
217 
218  return local;
219 }
220 
221 //______________________________________________________________________________
223 {
224  // Multiply with other transformation.
225  fTr.x = fRot[0] * other.fTr[0] + fRot[1] * other.fTr[1] + fRot[2] * other.fTr[2];
226  fTr.y = fRot[3] * other.fTr[0] + fRot[4] * other.fTr[1] + fRot[5] * other.fTr[2];
227  fTr.z = fRot[6] * other.fTr[0] + fRot[7] * other.fTr[1] + fRot[8] * other.fTr[2];
228 
229  double newrot[9];
230  for (int i = 0; i < 3; i++)
231  {
232  for (int j = 0; j < 3; j++)
233  {
234  newrot[3 * i + j] = fRot[3 * i] * other.fRot[j] +
235  fRot[3 * i + 1] * other.fRot[3 + j] +
236  fRot[3 * i + 2] * other.fRot[6 + j];
237  }
238  }
239  std::memcpy(fRot, newrot, sizeof(kIdRot));
240  return *this;
241 }
242 
243 //______________________________________________________________________________
245 {
246  // Multiply with a vector.
247  fTr.x = fRot[0] * vect.x + fRot[1] * vect.y + fRot[2] * vect.z;
248  fTr.y = fRot[3] * vect.x + fRot[4] * vect.y + fRot[5] * vect.z;
249  fTr.z = fRot[6] * vect.x + fRot[7] * vect.y + fRot[8] * vect.z;
250  return *this;
251 }
252 
253 //______________________________________________________________________________
254 UVector3 operator * (const UVector3& /*p*/, const UTransform3D& /*trans*/)
255 {
256  // Multiply matrix with translation.
257  UVector3 vect;
258  return vect;
259 }
static const double kDegToRad
Definition: UUtils.hh:51
UVector3 operator*(const UVector3 &, const UTransform3D &)
UVector3 LocalPoint(const UVector3 &global) const
static const double kIdRot[9]
Definition: UTransform3D.cc:23
virtual void RotateX(double angle)
#define local
Definition: adler32.cc:10
UVector3 LocalVector(const UVector3 &global) const
double x
Definition: UVector3.hh:136
UVector3 GlobalVector(const UVector3 &local) const
void SetAngles(double phi, double theta, double psi)
Definition: UTransform3D.cc:72
static const double s
Definition: G4SIunits.hh:150
UVector3 fTr
Definition: UTransform3D.hh:29
UVector3 GlobalPoint(const UVector3 &local) const
UTransform3D & operator*=(const UTransform3D &other)
virtual void RotateZ(double angle)
void Set(double xx, double yy, double zz)
Definition: UVector3.hh:245
double fRot[9]
Definition: UTransform3D.hh:30
double z
Definition: UVector3.hh:138
virtual void RotateY(double angle)
UTransform3D & operator=(const UTransform3D &other)
Definition: UTransform3D.cc:63
double y
Definition: UVector3.hh:137