Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JQuaternion3D.hh
Go to the documentation of this file.
1 #ifndef __JQUATERNION3D__
2 #define __JQUATERNION3D__
3 
4 #include <istream>
5 #include <ostream>
6 #include <limits>
7 #include <cmath>
8 
9 #include "JIO/JSerialisable.hh"
10 #include "JLang/JEquals.hh"
11 #include "JMath/JMath.hh"
12 #include "JGeometry3D/JVector3D.hh"
13 #include "JGeometry3D/JVersor3D.hh"
14 
15 
16 /**
17  * \author mdejong
18  */
19 
20 namespace JGEOMETRY3D {}
21 namespace JPP { using namespace JGEOMETRY3D; }
22 
23 namespace JGEOMETRY3D {
24 
25  using JIO::JReader;
26  using JIO::JWriter;
27  using JMATH::JMath;
28  using JLANG::JEquals;
29 
30 
31  /**
32  * This class represents a rotation.
33  */
34  struct JQuaternion2D {
35  protected:
36  /**
37  * Default constructor.
38  * This constructor corresponds to the identity operation.
39  */
41  __a(1.0),
42  __u(0.0)
43  {}
44 
45 
46  /**
47  * Constructor.
48  *
49  * \param theta rotation angle [rad]
50  */
51  JQuaternion2D(const double theta) :
52  __a(cos(0.5*theta)),
53  __u(sin(0.5*theta))
54  {}
55 
56 
57  public:
58  /**
59  * Get a value.
60  *
61  * \return a value
62  */
63  double getA() const
64  {
65  return __a;
66  }
67 
68 
69  /**
70  * Write quaternion from input.
71  *
72  * \param in input stream
73  * \param quaternion quaternion
74  * \return input stream
75  */
76  friend inline std::istream& operator>>(std::istream& in, JQuaternion2D& quaternion)
77  {
78  return in >> quaternion.__a >> quaternion.__u;
79  }
80 
81 
82  /**
83  * Write quaternion to output.
84  *
85  * \param out output stream
86  * \param quaternion quaternion
87  * \return output stream
88  */
89  friend inline std::ostream& operator<<(std::ostream& out, const JQuaternion2D& quaternion)
90  {
91  return out << quaternion.__a << ' ' << quaternion.__u;
92  }
93 
94 
95  /**
96  * Read quaternion from input.
97  *
98  * \param in reader
99  * \param quaternion quaternion
100  * \return reader
101  */
102  friend inline JReader& operator>>(JReader& in, JQuaternion2D& quaternion)
103  {
104  return in >> quaternion.__a >> quaternion.__u;
105  }
106 
107 
108  /**
109  * Write quaternion to output.
110  *
111  * \param out writer
112  * \param quaternion quaternion
113  * \return writer
114  */
115  friend inline JWriter& operator<<(JWriter& out, const JQuaternion2D& quaternion)
116  {
117  return out << quaternion.__a << quaternion.__u;
118  }
119 
120 
121  protected:
122  double __a;
123  double __u;
124  };
125 
126 
127  /**
128  * This class represents a rotation around the x-axis.
129  */
130  struct JQuaternion3X :
131  public JQuaternion2D
132  {
133  /**
134  * Default constructor.
135  */
137  JQuaternion2D()
138  {}
139 
140 
141  /**
142  * Constructor.
143  *
144  * \param theta rotation angle [rad]
145  */
146  JQuaternion3X(const double theta) :
147  JQuaternion2D(theta)
148  {}
149 
150 
151  /**
152  * Get b value.
153  *
154  * \return b value
155  */
156  double getB() const
157  {
158  return __u;
159  }
160  };
161 
162 
163  /**
164  * This class represents a rotation around the y-axis.
165  */
166  struct JQuaternion3Y :
167  public JQuaternion2D
168  {
169  /**
170  * Default constructor.
171  */
173  JQuaternion2D()
174  {}
175 
176 
177  /**
178  * Constructor.
179  *
180  * \param theta rotation angle [rad]
181  */
182  JQuaternion3Y(const double theta) :
183  JQuaternion2D(theta)
184  {}
185 
186 
187  /**
188  * Get c value.
189  *
190  * \return c value
191  */
192  double getC() const
193  {
194  return __u;
195  }
196  };
197 
198 
199  /**
200  * This class represents a rotation around the z-axis.
201  */
202  struct JQuaternion3Z :
203  public JQuaternion2D
204  {
205  /**
206  * Default constructor.
207  */
209  JQuaternion2D()
210  {}
211 
212 
213  /**
214  * Constructor.
215  *
216  * \param theta rotation angle [rad]
217  */
218  JQuaternion3Z(const double theta) :
219  JQuaternion2D(theta)
220  {}
221 
222 
223  /**
224  * Get d value.
225  *
226  * \return d value
227  */
228  double getD() const
229  {
230  return __u;
231  }
232  };
233 
234 
235  /**
236  * Data structure for quaternion in three dimensions.
237  *
238  * This class implements the JMATH::JMath and JLANG::JEquals interfaces.
239  */
241  public JMath <JQuaternion3D>,
242  public JMath <JQuaternion3D, JQuaternion3X>,
243  public JMath <JQuaternion3D, JQuaternion3Y>,
244  public JMath <JQuaternion3D, JQuaternion3Z>,
245  public JEquals<JQuaternion3D>
246  {
247  public:
248 
253 
254 
255  /**
256  * Default constructor.
257  */
259  __a(0.0),
260  __b(0.0),
261  __c(0.0),
262  __d(0.0)
263  {}
264 
265 
266  /**
267  * Constructor.
268  *
269  * \param a a value
270  * \param b b value
271  * \param c c value
272  * \param d d value
273  */
274  JQuaternion3D(const double a,
275  const double b,
276  const double c,
277  const double d) :
278  __a(a),
279  __b(b),
280  __c(c),
281  __d(d)
282  {}
283 
284 
285  /**
286  * Constructor.
287  *
288  * This constructor represents a rotation around the given axis by the given angle.
289  *
290  * \param theta rotation angle [rad]
291  * \param dir rotation axis
292  */
293  JQuaternion3D(const double theta,
294  const JVersor3D& dir)
295  {
296  const double ct = cos(0.5*theta);
297  const double st = sin(0.5*theta);
298 
299  __a = ct;
300  __b = st * dir.getDX();
301  __c = st * dir.getDY();
302  __d = st * dir.getDZ();
303  }
304 
305 
306  /**
307  * Constructor.
308  *
309  * \param qx rotation around x-axis
310  * \param qy rotation around y-axis
311  * \param qz rotation around x-axis
312  */
314  const JQuaternion3Y& qy,
315  const JQuaternion3Z& qz) :
316  __a(1.0),
317  __b(0.0),
318  __c(0.0),
319  __d(0.0)
320  {
321  mul(qz).mul(qy).mul(qx);
322  }
323 
324 
325  /**
326  * Get quaternion.
327  *
328  * \return quaternion
329  */
331  {
332  return static_cast<const JQuaternion3D&>(*this);
333  }
334 
335 
336  /**
337  * Get quaternion.
338  *
339  * \return quaternion
340  */
342  {
343  return static_cast<JQuaternion3D&>(*this);
344  }
345 
346 
347  /**
348  * Set quaternion.
349  *
350  * \param quaternion quaternion
351  */
352  void setQuaternion(const JQuaternion3D& quaternion)
353  {
354  static_cast<JQuaternion3D&>(*this) = quaternion;
355  }
356 
357 
358  /**
359  * Type conversion operator.
360  *
361  * \return position
362  */
363  operator JVector3D() const
364  {
365  return JVector3D(this->getB(), this->getC(), this->getD());
366  }
367 
368 
369  /**
370  * Type conversion operator.
371  *
372  * \return direction
373  */
374  operator JVersor3D() const
375  {
376  return JVersor3D(this->getB(), this->getC(), this->getD());
377  }
378 
379 
380  /**
381  * Get a value.
382  *
383  * \return a value
384  */
385  double getA() const
386  {
387  return __a;
388  }
389 
390 
391  /**
392  * Get b value.
393  *
394  * \return b value
395  */
396  double getB() const
397  {
398  return __b;
399  }
400 
401 
402  /**
403  * Get c value.
404  *
405  * \return c value
406  */
407  double getC() const
408  {
409  return __c;
410  }
411 
412 
413  /**
414  * Get d value.
415  *
416  * \return d value
417  */
418  double getD() const
419  {
420  return __d;
421  }
422 
423 
424  /**
425  * Set to identity matrix
426  *
427  * \return this quaternion
428  */
430  {
431  __a = 1.0;
432  __b = 0.0;
433  __c = 0.0;
434  __d = 0.0;
435 
436  return *this;
437  }
438 
439 
440  /**
441  * Conjugate quaternion.
442  *
443  * \return this quaternion
444  */
446  {
447  __b = -__b;
448  __c = -__c;
449  __d = -__d;
450 
451  return *this;
452  }
453 
454 
455  /**
456  * Negate quaternion.
457  *
458  * \return this quaternion
459  */
461  {
462  __a = -__a;
463  __b = -__b;
464  __c = -__c;
465  __d = -__d;
466 
467  return *this;
468  }
469 
470 
471  /**
472  * Add quaternion.
473  *
474  * \param quaternion quaternion
475  * \return this quaternion
476  */
477  JQuaternion3D& add(const JQuaternion3D& quaternion)
478  {
479  __a += quaternion.getA();
480  __b += quaternion.getB();
481  __c += quaternion.getC();
482  __d += quaternion.getD();
483 
484  return *this;
485  }
486 
487 
488  /**
489  * Subtract quaternion.
490  *
491  * \param quaternion quaternion
492  * \return this quaternion
493  */
494  JQuaternion3D& sub(const JQuaternion3D& quaternion)
495  {
496  __a -= quaternion.getA();
497  __b -= quaternion.getB();
498  __c -= quaternion.getC();
499  __d -= quaternion.getD();
500 
501  return *this;
502  }
503 
504 
505  /**
506  * Scale quaternion.
507  *
508  * \param factor multiplication factor
509  * \return this quaternion
510  */
511  JQuaternion3D& mul(const double factor)
512  {
513  __a *= factor;
514  __b *= factor;
515  __c *= factor;
516  __d *= factor;
517 
518  return *this;
519  }
520 
521 
522  /**
523  * Scale quaternion.
524  *
525  * \param factor division factor
526  * \return this quaternion
527  */
528  JQuaternion3D& div(const double factor)
529  {
530  __a /= factor;
531  __b /= factor;
532  __c /= factor;
533  __d /= factor;
534 
535  return *this;
536  }
537 
538 
539  /**
540  * Quaternion multiplicaion.
541  *
542  * This method evaluates the Hamilton product (also called cross product).
543  *
544  * \param first first quaternion
545  * \param second second quaternion
546  * \return this quaternion
547  */
549  {
550  __a = first.getA() * second.getA() - first.getB() * second.getB();
551  __b = first.getA() * second.getB() + first.getB() * second.getA();
552  __c = first.getC() * second.getA() + first.getD() * second.getB();
553  __d = -first.getC() * second.getB() + first.getD() * second.getA();
554 
555  return *this;
556  }
557 
558 
559  /**
560  * Quaternion multiplicaion.
561  *
562  * This method evaluates the Hamilton product (or cross product).
563  *
564  * \param first first quaternion
565  * \param second second quaternion
566  * \return this quaternion
567  */
569  const JQuaternion3Y& second)
570  {
571  __a = first.getA() * second.getA() - first.getC() * second.getC();
572  __b = first.getB() * second.getA() - first.getD() * second.getC();
573  __c = first.getA() * second.getC() + first.getC() * second.getA();
574  __d = first.getB() * second.getC() + first.getD() * second.getA();
575 
576  return *this;
577  }
578 
579 
580  /**
581  * Quaternion multiplicaion.
582  *
583  * This method evaluates the Hamilton product (or cross product).
584  *
585  * \param first first quaternion
586  * \param second second quaternion
587  * \return this quaternion
588  */
590  const JQuaternion3Z& second)
591  {
592  __a = first.getA() * second.getA() - first.getD() * second.getD();
593  __b = first.getB() * second.getA() + first.getC() * second.getD();
594  __c = -first.getB() * second.getD() + first.getC() * second.getA();
595  __d = first.getA() * second.getD() + first.getD() * second.getA();
596 
597  return *this;
598  }
599 
600 
601  /**
602  * Quaternion multiplicaion.
603  *
604  * This method evaluates the Hamilton product (or cross product).
605  *
606  * \param first first quaternion
607  * \param second second quaternion
608  * \return this quaternion
609  */
611  const JQuaternion3D& second)
612  {
613  __a = first.getA() * second.getA() - first.getB() * second.getB() - first.getC() * second.getC() - first.getD() * second.getD();
614  __b = first.getA() * second.getB() + first.getB() * second.getA() + first.getC() * second.getD() - first.getD() * second.getC();
615  __c = first.getA() * second.getC() - first.getB() * second.getD() + first.getC() * second.getA() + first.getD() * second.getB();
616  __d = first.getA() * second.getD() + first.getB() * second.getC() - first.getC() * second.getB() + first.getD() * second.getA();
617 
618  return *this;
619  }
620 
621 
622  /**
623  * Quaternion multiplicaion.
624  *
625  * \param qx rotation around x-axis
626  * \param qy rotation around y-axis
627  * \param qz rotation around x-axis
628  * \return this quaternion
629  */
631  const JQuaternion3Y& qy,
632  const JQuaternion3Z& qz)
633  {
634  return *this = JQuaternion3D().setIdentity().mul(qz).mul(qy).mul(qx);
635  }
636 
637 
638  /**
639  * Rotate.
640  *
641  * \param __x x value
642  * \param __y y value
643  * \param __z z value
644  */
645  void rotate(double& __x, double& __y, double& __z) const
646  {
647  const double qx = 2.0 * (__c*__z - __d*__y);
648  const double qy = 2.0 * (__d*__x - __b*__z);
649  const double qz = 2.0 * (__b*__y - __c*__x);
650 
651  const double x = __x + __c*qz - __d*qy + __a*qx;
652  const double y = __y - __b*qz + __a*qy + __d*qx;
653  const double z = __z + __a*qz + __b*qy - __c*qx;
654 
655  __x = x;
656  __y = y;
657  __z = z;
658  }
659 
660 
661  /**
662  * Rotate back.
663  *
664  * \param __x x value
665  * \param __y y value
666  * \param __z z value
667  */
668  void rotate_back(double& __x, double& __y, double& __z) const
669  {
670  const double qx = 2.0 * (__d*__y - __c*__z);
671  const double qy = 2.0 * (__b*__z - __d*__x);
672  const double qz = 2.0 * (__c*__x - __b*__y);
673 
674  const double x = __x - __c*qz + __d*qy + __a*qx;
675  const double y = __y + __b*qz + __a*qy - __d*qx;
676  const double z = __z + __a*qz - __b*qy + __c*qx;
677 
678  __x = x;
679  __y = y;
680  __z = z;
681  }
682 
683 
684  /**
685  * Check equality.
686  *
687  * \param quaternion quaternion
688  * \param precision numerical precision
689  * \return true if quaternions are equal; else false
690  */
691  bool equals(const JQuaternion3D& quaternion,
692  const double precision = std::numeric_limits<double>::min()) const
693  {
694  return (fabs(getA() - quaternion.getA()) <= precision &&
695  fabs(getB() - quaternion.getB()) <= precision &&
696  fabs(getC() - quaternion.getC()) <= precision &&
697  fabs(getD() - quaternion.getD()) <= precision);
698  }
699 
700 
701  /**
702  * Get length squared.
703  *
704  * \return square of length
705  */
706  double getLengthSquared() const
707  {
708  return getA()*getA() + getB()*getB() + getC()*getC() + getD()*getD();
709  }
710 
711 
712  /**
713  * Get length.
714  *
715  * \return length
716  */
717  double getLength() const
718  {
719  return sqrt(getLengthSquared());
720  }
721 
722 
723  /**
724  * Get squared of distance to quaternion.
725  *
726  * \param quaternion quaternion
727  * \return square of distance
728  */
729  double getDistanceSquared(const JQuaternion3D& quaternion) const
730  {
731  return JQuaternion3D(quaternion).sub(*this).getLengthSquared();
732  }
733 
734 
735  /**
736  * Get distance to quaternion.
737  *
738  * \param quaternion quaternion
739  * \return distance
740  */
741  double getDistance(const JQuaternion3D& quaternion) const
742  {
743  return sqrt(getDistanceSquared(quaternion));
744  }
745 
746 
747  /**
748  * Get dot product.
749  *
750  * \param quaternion quaternion
751  * \return dot product
752  */
753  double getDot(const JQuaternion3D& quaternion) const
754  {
755  return
756  getA() * quaternion.getA() -
757  getB() * quaternion.getB() -
758  getC() * quaternion.getC() -
759  getD() * quaternion.getD();
760  }
761 
762 
763  /**
764  * Write quaternion from input.
765  *
766  * \param in input stream
767  * \param quaternion quaternion
768  * \return input stream
769  */
770  friend inline std::istream& operator>>(std::istream& in, JQuaternion3D& quaternion)
771  {
772  in >> quaternion.__a;
773  in >> quaternion.__b;
774  in >> quaternion.__c;
775  in >> quaternion.__d;
776 
777  return in;
778  }
779 
780 
781  /**
782  * Write quaternion to output.
783  *
784  * \param out output stream
785  * \param quaternion quaternion
786  * \return output stream
787  */
788  friend inline std::ostream& operator<<(std::ostream& out, const JQuaternion3D& quaternion)
789  {
790  out << quaternion.getA() << ' '
791  << quaternion.getB() << ' '
792  << quaternion.getC() << ' '
793  << quaternion.getD();
794 
795  return out;
796  }
797 
798 
799  /**
800  * Read quaternion from input.
801  *
802  * \param in reader
803  * \param quaternion quaternion
804  * \return reader
805  */
806  friend inline JReader& operator>>(JReader& in, JQuaternion3D& quaternion)
807  {
808  in >> quaternion.__a;
809  in >> quaternion.__b;
810  in >> quaternion.__c;
811  in >> quaternion.__d;
812 
813  return in;
814  }
815 
816 
817  /**
818  * Write quaternion to output.
819  *
820  * \param out writer
821  * \param quaternion quaternion
822  * \return writer
823  */
824  friend inline JWriter& operator<<(JWriter& out, const JQuaternion3D& quaternion)
825  {
826  out << quaternion.getA();
827  out << quaternion.getB();
828  out << quaternion.getC();
829  out << quaternion.getD();
830 
831  return out;
832  }
833 
834 
835  /**
836  * Normalise quaternion.
837  *
838  * \return this quaternion
839  */
841  {
842  const double v = getLength();
843 
844  if (v != 0.0) {
845  mul(1.0 / v);
846  }
847 
848  return *this;
849  }
850 
851  protected:
852  double __a;
853  double __b;
854  double __c;
855  double __d;
856  };
857 }
858 
859 #endif
double getDot(const JQuaternion3D &quaternion) const
Get dot product.
Interface for binary output.
JQuaternion3X()
Default constructor.
double getB() const
Get b value.
Auxiliary base class for aritmetic operations of derived class types.
Definition: JMath.hh:26
JQuaternion3D(const double theta, const JVersor3D &dir)
Constructor.
JQuaternion2D()
Default constructor.
JQuaternion3X(const double theta)
Constructor.
This class represents a rotation around the x-axis.
friend std::istream & operator>>(std::istream &in, JQuaternion2D &quaternion)
Write quaternion from input.
double getB() const
Get b value.
double getA() const
Get a value.
double getLengthSquared() const
Get length squared.
esac print_variable DETECTOR INPUT_FILE OUTPUT_FILE CDF for TYPE in
Definition: JSirene.sh:45
void rotate_back(double &__x, double &__y, double &__z) const
Rotate back.
JQuaternion3D & add(const JQuaternion3D &quaternion)
Add quaternion.
double getDistanceSquared(const JQuaternion3D &quaternion) const
Get squared of distance to quaternion.
JQuaternion3Z(const double theta)
Constructor.
double getC() const
Get c value.
friend std::ostream & operator<<(std::ostream &out, const JQuaternion2D &quaternion)
Write quaternion to output.
fi JEventTimesliceWriter a
JQuaternion3D & mul(const JQuaternion3D &first, const JQuaternion3Z &second)
Quaternion multiplicaion.
JQuaternion3Z()
Default constructor.
JQuaternion3D & mul(const double factor)
Scale quaternion.
JQuaternion3D & mul(const JQuaternion3D &first, const JQuaternion3Y &second)
Quaternion multiplicaion.
then echo The file $DIR KM3NeT_00000001_00000000 root already please rename or remove it first
const JQuaternion3D & getQuaternion() const
Get quaternion.
JQuaternion3D & sub(const JQuaternion3D &quaternion)
Subtract quaternion.
JQuaternion3Y()
Default constructor.
Data structure for vector in three dimensions.
Definition: JVector3D.hh:33
void setQuaternion(const JQuaternion3D &quaternion)
Set quaternion.
This class represents a rotation.
double getDY() const
Get y direction.
Definition: JVersor3D.hh:103
double getDX() const
Get x direction.
Definition: JVersor3D.hh:92
This class represents a rotation around the z-axis.
then print_variable DETECTOR INPUT_FILE INTERMEDIATE_FILE check_input_file $DETECTOR $INPUT_FILE check_output_file $INTERMEDIATE_FILE $OUTPUT_FILE JMCEvt f $INPUT_FILE o $INTERMEDIATE_FILE d
Definition: JPath.sh:52
Template definition of auxiliary base class for comparison of data structures.
Definition: JEquals.hh:24
JQuaternion3D & mul(const JQuaternion3D &first, const JQuaternion3X &second)
Quaternion multiplicaion.
Interface for binary input.
friend JReader & operator>>(JReader &in, JQuaternion2D &quaternion)
Read quaternion from input.
double getD() const
Get d value.
JQuaternion3D & mul(const JQuaternion3D &first, const JQuaternion3D &second)
Quaternion multiplicaion.
Data structure for quaternion in three dimensions.
JQuaternion2D(const double theta)
Constructor.
JQuaternion3D & setIdentity()
Set to identity matrix.
This class represents a rotation around the y-axis.
friend std::ostream & operator<<(std::ostream &out, const JQuaternion3D &quaternion)
Write quaternion to output.
double getD() const
Get d value.
friend JReader & operator>>(JReader &in, JQuaternion3D &quaternion)
Read quaternion from input.
double getC() const
Get c value.
JQuaternion3D()
Default constructor.
bool equals(const JQuaternion3D &quaternion, const double precision=std::numeric_limits< double >::min()) const
Check equality.
Base class for data structures with artithmetic capabilities.
double getA() const
Get a value.
JQuaternion3D & normalise()
Normalise quaternion.
JQuaternion3Y(const double theta)
Constructor.
JQuaternion3D(const JQuaternion3X &qx, const JQuaternion3Y &qy, const JQuaternion3Z &qz)
Constructor.
JQuaternion3D & mul(const JQuaternion3X &qx, const JQuaternion3Y &qy, const JQuaternion3Z &qz)
Quaternion multiplicaion.
data_type v[N+1][M+1]
Definition: JPolint.hh:707
Data structure for normalised vector in three dimensions.
Definition: JVersor3D.hh:23
JQuaternion3D(const double a, const double b, const double c, const double d)
Constructor.
friend std::istream & operator>>(std::istream &in, JQuaternion3D &quaternion)
Write quaternion from input.
JQuaternion3D & div(const double factor)
Scale quaternion.
JQuaternion3D & negate()
Negate quaternion.
friend JWriter & operator<<(JWriter &out, const JQuaternion3D &quaternion)
Write quaternion to output.
double getDZ() const
Get z direction.
Definition: JVersor3D.hh:114
void rotate(double &__x, double &__y, double &__z) const
Rotate.
JQuaternion3D & getQuaternion()
Get quaternion.
double getDistance(const JQuaternion3D &quaternion) const
Get distance to quaternion.
friend JWriter & operator<<(JWriter &out, const JQuaternion2D &quaternion)
Write quaternion to output.
double getLength() const
Get length.
JQuaternion3D & conjugate()
Conjugate quaternion.