GeoModel - GeoModelCore
TinyHepTransform.h
1 /*
2  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #ifndef _TINYHEPTRANSFORM_H_
6 #define _TINYHEPTRANSFORM_H_
7 //-------------------------------------------------------------------------//
8 // //
9 // Tiny HepTransforms Joe Boudreau September 2003 //
10 // //
11 // These are essentially alternate representations of Transform3D //
12 // that are designed for memory optimization. //
13 // //
14 // This header file includes the following classes: //
15 // //
16 // tiny::HepTranslate3D //
17 // tiny::HepTranslateX3D //
18 // tiny::HepTranslateY3D //
19 // tiny::HepTranslateZ3D //
20 // tiny::HepRotate3D //
21 // tiny::HepRotateX3D //
22 // tiny::HepRotateY3D //
23 // tiny::HepRotateZ3D //
24 // tiny::HepReflect3D //
25 // tiny::HepReflectX3D //
26 // tiny::HepReflectY3D //
27 // tiny::HepReflectZ3D //
28 // tiny::HepScale3D //
29 // tiny::HepScale3XD //
30 // tiny::HepScale3YD //
31 // tiny::HepScale3ZD //
32 // //
33 // tiny::Transform3D //
34 // tiny::HepProperTransform3D //
35 // //
36 // The "Input classes" all contain constructors with the same signature //
37 // as their CLHEP counterparts. However, they do not store more info //
38 // than what they need; for example, HepTranslateZ3D stores just one //
39 // floating point number. However it can cast itself to a Transform3D //
40 // and so can be used exactly as a regular Transform3D. (Sometimes //
41 // you will need explicit casts in order to coax this behaviour). //
42 // //
43 // The "output classes" can be assigned the value of the Transform3D //
44 // but store it in a memory-optimized way. Six floats for a proper //
45 // transform and nine floats for a transform with scaling. In case //
46 // an improper CLHEP Transform is assigned to a tiny transform, a run //
47 // time error will occur. //
48 // //
49 //-------------------------------------------------------------------------//
50 
51 #include "GeoModelKernel/GeoDefinitions.h"
52 
53 // #include "CLHEP/Geometry/Point3D.h"
54 // #include "CLHEP/Vector/ThreeVector.h"
55 
56 #include <iostream>
57 #include <stdexcept>
58 
59 namespace tiny {
60 
61  class Transform {
62 
63  public:
64 
65  virtual operator ::Transform3D() const = 0;
66 
67  };
68 
69 
70  class HepReflectX3D: public Transform {
71 
72  public:
73 
74  virtual operator ::Transform3D() const {
75  return ::HepReflectX3D();
76  }
77 
78  };
79 
80  class HepReflectY3D: public Transform {
81 
82  public:
83 
84  virtual operator ::Transform3D() const {
85  return ::HepReflectY3D();
86  }
87 
88  };
89 
90  class HepReflectZ3D: public Transform {
91 
92  public:
93 
94  virtual operator ::Transform3D() const {
95  return ::HepReflectZ3D();
96  }
97 
98  };
99 
100  class HepTranslateX3D: public Transform {
101 
102  public:
103 
104  inline HepTranslateX3D(double a):
105  _a(a) {}
106 
107  virtual operator ::Transform3D() const {
108  return ::HepTranslateX3D(_a);
109  }
110 
111  private:
112 
113  float _a;
114 
115  };
116 
117  class HepTranslateY3D: public Transform {
118 
119  public:
120 
121  inline HepTranslateY3D(double a):
122  _a(a) {}
123 
124  virtual operator ::Transform3D() const {
125  return ::HepTranslateY3D(_a);
126  }
127 
128  private:
129 
130  float _a;
131 
132  };
133 
134  class HepTranslateZ3D: public Transform {
135 
136  public:
137 
138  inline HepTranslateZ3D(double a):
139  _a(a) {}
140 
141  virtual operator ::Transform3D() const {
142  return ::HepTranslateZ3D(_a);
143  }
144 
145  private:
146 
147  float _a;
148 
149  };
150 
151  class HepScaleX3D: public Transform {
152 
153  public:
154 
155  inline HepScaleX3D(double a):
156  _a(a) {}
157 
158  virtual operator ::Transform3D() const {
159  return ::HepScaleX3D(_a);
160  }
161 
162  private:
163 
164  float _a;
165 
166  };
167 
168  class HepScaleY3D: public Transform {
169 
170  public:
171 
172  inline HepScaleY3D(double a):
173  _a(a) {}
174 
175  virtual operator ::Transform3D() const {
176  return ::HepScaleY3D(_a);
177  }
178 
179  private:
180 
181  float _a;
182 
183  };
184 
185  class HepScaleZ3D: public Transform {
186 
187  public:
188 
189  inline HepScaleZ3D(double a):
190  _a(a) {}
191 
192  virtual operator ::Transform3D() const {
193  return ::HepScaleZ3D(_a);
194  }
195 
196  private:
197 
198  float _a;
199 
200  };
201 
202  class HepRotateX3D: public Transform {
203 
204  public:
205 
206  inline HepRotateX3D(double a):
207  _a(a) {}
208 
209 
210  virtual operator ::Transform3D() const {
211  return ::HepRotateX3D(_a);
212  }
213 
214  private:
215 
216  float _a;
217 
218  };
219 
220  class HepRotateY3D: public Transform {
221 
222  public:
223 
224  inline HepRotateY3D(double a):
225  _a(a) {}
226 
227  virtual operator ::Transform3D() const {
228  return ::HepRotateY3D(_a);
229  }
230 
231  private:
232 
233  float _a;
234 
235  };
236 
237  class HepRotateZ3D: public Transform {
238 
239  public:
240 
241  inline HepRotateZ3D(double a):
242  _a(a) {}
243 
244  virtual operator ::Transform3D() const {
245  return ::HepRotateZ3D(_a);
246  }
247 
248  private:
249 
250  float _a;
251 
252  };
253 
254 
255 
256  class HepRotate3D: public Transform {
257 
258  public:
259 
260  inline HepRotate3D(const Rotation3D &m) {
261  double angle;
262  Vector3D axis;
263  m.getAngleAxis(angle, axis);
264  axis.setMag(angle);
265  ax=axis.x(); ay = axis.y(); az=axis.z();
266 
267  }
268 
269  inline HepRotate3D(double a, const Vector3D<double> & v) {
270  Vector3D axis=v;
271  axis.setMag(a);
272  ax=axis.x(); ay=axis.y(); az=axis.z();
273  }
274 
275  inline HepRotate3D(double a,
276  const Vector3D & p1,
277  const Vector3D & p2) {
278  ::HepRotate3D tmp(a, p1, p2);
279  const Rotation3D & m = tmp.rotation();
280  double angle;
281  Vector3D axis;
282  m.getAngleAxis(angle, axis);
283  axis.setMag(angle);
284  ax=axis.x(); ay = axis.y(); az=axis.z();
285  }
286 
287  inline HepRotate3D(const Vector3D & fr1,
288  const Vector3D & fr2,
289  const Vector3D & to1,
290  const Vector3D & to2) {
291  ::HepRotate3D tmp(fr1, fr2, to1, to2);
292  const Rotation3D & m = tmp.rotation();
293  double angle;
294  Vector3D axis;
295  m.getAngleAxis(angle, axis);
296  axis.setMag(angle);
297  ax=axis.x(); ay = axis.y(); az=axis.z();
298  }
299 
300  virtual operator ::Transform3D() const {
301  return ::HepRotate3D(sqrt(ax*ax+ay*ay+az*az), Vector3D<double> (ax,ay,az));
302  }
303 
304  private:
305 
306  float ax, ay, az;
307 
308  };
309 
310  class HepTranslate3D: public Transform {
311 
312  public:
313  inline HepTranslate3D (const Vector3D & v):
314  ax(v.x()),ay(v.y()), az(v.z()){}
315 
316  inline HepTranslate3D (double dx, double dy, double dz):
317  ax(dx),ay(dy),az(dz) {}
318 
319  virtual operator ::Transform3D() const {
320  return ::HepTranslate3D(ax,ay,az);
321  }
322 
323  private:
324  float ax, ay, az;
325  };
326 
327  class HepScale3D: public Transform {
328 
329  public:
330 
331  inline HepScale3D (double s):
332  ax(s),ay(s), az(s){}
333 
334  inline HepScale3D (double sx, double sy, double sz):
335  ax(sx),ay(sy),az(sz) {}
336 
337  virtual operator ::Transform3D() const {
338  return ::HepScale3D(ax,ay,az);
339  }
340 
341  private:
342  float ax, ay, az;
343  };
344 
345  class HepReflect3D: public Transform {
346 
347  public:
348 
349  inline HepReflect3D(double a, double b, double c, double d) {
350  double mag = sqrt(a*a+b*b+c*c);
351  d = d/mag;
352  ax = d*a/mag;
353  ay = d*b/mag;
354  az = d*c/mag;
355 
356  }
357 
358  inline HepReflect3D(const Normal3D<double> & normal,
359  const Vector3D & point) {
360  Normal3D<double> nNorm=normal;
361  nNorm.setMag(1.0);
362  double d = nNorm*point;
363  nNorm.setMag(d);
364  }
365 
366  virtual operator ::Transform3D() const {
367  double mag = sqrt(ax*ax+ay*ay+az*az);
368  return ::HepReflect3D(ax/mag,ay/mag,az/mag ,mag);
369  }
370 
371  private:
372  float ax, ay, az;
373  };
374 
375 
377 
378  public:
379 
380  inline HepProperTransform3D():
381  tx(0),ty(0), tz(0), rx(0), ry(0), rz(0) {}
382 
383 
384  inline HepProperTransform3D(const ::Transform3D & source) {
385  Scale3D scale;
386  Rotate3D rotate;
387  Translate3D translate;
388 
389  source.getDecomposition(scale, rotate, translate);
390  const double EPS=5E-5;
391  if (fabs(scale.xx()-1.0)>EPS || fabs(scale.yy()-1.0)>EPS || fabs(scale.zz()-1.0)>EPS) {
392 
393  throw std::range_error("tiny::HepProperTransform3D detects an improper transformation (scaling or reflection)");
394  }
395 
396  double angle;
397  Rotation3D rotation( HepRep3x3(rotate.xx(), rotate.xy(), rotate.xz(),
398  rotate.yx(), rotate.yy(), rotate.yz(),
399  rotate.zx(), rotate.zy(), rotate.zz()));
400  Vector3D axis;
401  rotation.getAngleAxis(angle, axis);
402  axis.setMag(angle);
403  rx=axis.x(); ry = axis.y(); rz=axis.z();
404 
405  tx = translate.dx();
406  ty = translate.dy();
407  tz = translate.dz();
408 
409  }
410 
411  inline const HepProperTransform3D & operator = (const ::Transform3D & source) {
412  Scale3D scale;
413  Rotate3D rotate;
414  Translate3D translate;
415 
416  source.getDecomposition(scale, rotate, translate);
417  const double EPS=5E-5;
418  if (fabs(scale.xx()-1.0)>EPS || fabs(scale.yy()-1.0)>EPS || fabs(scale.zz()-1.0)>EPS) {
419  throw std::range_error("tiny::HepProperTransform3D detects an improper transformation (scaling or reflection)");
420  }
421 
422  double angle;
423  Rotation3D rotation( HepRep3x3(rotate.xx(), rotate.xy(), rotate.xz(),
424  rotate.yx(), rotate.yy(), rotate.yz(),
425  rotate.zx(), rotate.zy(), rotate.zz()));
426  Vector3D axis;
427  rotation.getAngleAxis(angle, axis);
428  axis.setMag(angle);
429  rx=axis.x(); ry = axis.y(); rz=axis.z();
430 
431  tx = translate.dx();
432  ty = translate.dy();
433  tz = translate.dz();
434  return *this;
435  }
436 
437  virtual operator ::Transform3D() const {
438  return ::Transform3D(CLHEP::Rotation3D(Vector3D(rx,ry,rz),sqrt(rx*rx+ry*ry+rz*rz)),
439  Vector3D(tx,ty,tz));
440  }
441 
442  private:
443 
444  float tx, ty, tz;
445  float rx, ry, rz;
446 
447  };
448 
449 
450  class Transform3D: public Transform {
451 
452  public:
453 
454  inline Transform3D():
455  tx(0),ty(0), tz(0), rx(0), ry(0), rz(0), sx(0), sy(0), sz(0) {}
456 
457 
458  inline Transform3D(const ::Transform3D & source) {
459  Scale3D scale;
460  Rotate3D rotate;
461  Translate3D translate;
462 
463  source.getDecomposition(scale, rotate, translate);
464 
465  double angle;
466  Rotation3D rotation( HepRep3x3(rotate.xx(), rotate.xy(), rotate.xz(),
467  rotate.yx(), rotate.yy(), rotate.yz(),
468  rotate.zx(), rotate.zy(), rotate.zz()));
469  Vector3D axis;
470  rotation.getAngleAxis(angle, axis);
471  axis.setMag(angle);
472  rx=axis.x(); ry = axis.y(); rz=axis.z();
473 
474  tx = translate.dx();
475  ty = translate.dy();
476  tz = translate.dz();
477 
478  sx = scale.xx();
479  sy = scale.yy();
480  sz = scale.zz();
481 
482  }
483 
484  inline const Transform3D & operator = (const ::Transform3D & source) {
485  Scale3D scale;
486  Rotate3D rotate;
487  Translate3D translate;
488 
489  source.getDecomposition(scale, rotate, translate);
490 
491  double angle;
492  Rotation3D rotation( HepRep3x3(rotate.xx(), rotate.xy(), rotate.xz(),
493  rotate.yx(), rotate.yy(), rotate.yz(),
494  rotate.zx(), rotate.zy(), rotate.zz()));
495  Vector3D axis;
496  rotation.getAngleAxis(angle, axis);
497  axis.setMag(angle);
498  rx=axis.x(); ry = axis.y(); rz=axis.z();
499 
500  tx = translate.dx();
501  ty = translate.dy();
502  tz = translate.dz();
503 
504  sx = scale.xx();
505  sy = scale.yy();
506  sz = scale.zz();
507 
508  return *this;
509  }
510 
511  virtual operator ::Transform3D() const {
512  return ::Transform3D(CLHEP::Rotation3D(Vector3D(rx,ry,rz),sqrt(rx*rx+ry*ry+rz*rz)),
513  Vector3D(tx,ty,tz))*Scale3D(sx,sy,sz);
514  }
515 
516  private:
517 
518  float tx, ty, tz;
519  float rx, ry, rz;
520  float sx, sy, sz;
521  };
522 
523 }
524 #endif