1 // Created on: 2010-05-11
2 // Created by: Kirill GAVRILOV
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
19 #include <Standard.hxx>
20 #include <Standard_DefineAlloc.hxx>
21 #include <Standard_Handle.hxx>
23 #include <Standard_Real.hxx>
24 #include <Standard_Boolean.hxx>
25 #include <gp_EulerSequence.hxx>
26 #include <gp_Vec.hxx>
27 class gp_Vec;
28 class gp_Mat;
31 //! Represents operation of rotation in 3d space as queternion
32 //! and implements operations with rotations basing on
33 //! quaternion mathematics.
34 //!
35 //! In addition, provides methods for conversion to and from other
36 //! representatons of rotation (3*3 matrix, vector and
37 //! angle, Euler angles)
38 class gp_Quaternion
39 {
40 public:
42   DEFINE_STANDARD_ALLOC
45   //! Creates an identity quaternion
46   gp_Quaternion();
48   //! Creates quaternion directly from component values
49   gp_Quaternion(const Standard_Real x, const Standard_Real y, const Standard_Real z, const Standard_Real w);
51   //! Creates quaternion representing shortest-arc rotation
52   //! operator producing vector theVecTo from vector theVecFrom.
53   gp_Quaternion(const gp_Vec& theVecFrom, const gp_Vec& theVecTo);
55   //! Creates quaternion representing shortest-arc rotation
56   //! operator producing vector theVecTo from vector theVecFrom.
57   //! Additional vector theHelpCrossVec defines preferred direction for
58   //! rotation and is used when theVecTo and theVecFrom are directed
59   //! oppositely.
60   gp_Quaternion(const gp_Vec& theVecFrom, const gp_Vec& theVecTo, const gp_Vec& theHelpCrossVec);
62   //! Creates quaternion representing rotation on angle
63   //! theAngle around vector theAxis
64   gp_Quaternion(const gp_Vec& theAxis, const Standard_Real theAngle);
66   //! Creates quaternion from rotation matrix 3*3
67   //! (which should be orthonormal skew-symmetric matrix)
68   gp_Quaternion(const gp_Mat& theMat);
70   //! Simple equal test without precision
71   Standard_EXPORT Standard_Boolean IsEqual (const gp_Quaternion& theOther) const;
73   //! Sets quaternion to shortest-arc rotation producing
74   //! vector theVecTo from vector theVecFrom.
75   //! If vectors theVecFrom and theVecTo are opposite then rotation
76   //! axis is computed as theVecFrom ^ (1,0,0) or theVecFrom ^ (0,0,1).
77   Standard_EXPORT void SetRotation (const gp_Vec& theVecFrom, const gp_Vec& theVecTo);
79   //! Sets quaternion to shortest-arc rotation producing
80   //! vector theVecTo from vector theVecFrom.
81   //! If vectors theVecFrom and theVecTo are opposite then rotation
82   //! axis is computed as theVecFrom ^ theHelpCrossVec.
83   Standard_EXPORT void SetRotation (const gp_Vec& theVecFrom, const gp_Vec& theVecTo, const gp_Vec& theHelpCrossVec);
85   //! Create a unit quaternion from Axis+Angle representation
86   Standard_EXPORT void SetVectorAndAngle (const gp_Vec& theAxis, const Standard_Real theAngle);
88   //! Convert a quaternion to Axis+Angle representation,
89   //! preserve the axis direction and angle from -PI to +PI
90   Standard_EXPORT void GetVectorAndAngle (gp_Vec& theAxis, Standard_Real& theAngle) const;
92   //! Create a unit quaternion by rotation matrix
93   //! matrix must contain only rotation (not scale or shear)
94   //!
95   //! For numerical stability we find first the greatest component of quaternion
96   //! and than search others from this one
97   Standard_EXPORT void SetMatrix (const gp_Mat& theMat);
99   //! Returns rotation operation as 3*3 matrix
100   Standard_EXPORT gp_Mat GetMatrix() const;
102   //! Create a unit quaternion representing rotation defined
103   //! by generalized Euler angles
104   Standard_EXPORT void SetEulerAngles (const gp_EulerSequence theOrder, const Standard_Real theAlpha, const Standard_Real theBeta, const Standard_Real theGamma);
106   //! Returns Euler angles describing current rotation
107   Standard_EXPORT void GetEulerAngles (const gp_EulerSequence theOrder, Standard_Real& theAlpha, Standard_Real& theBeta, Standard_Real& theGamma) const;
109   void Set (const Standard_Real x, const Standard_Real y, const Standard_Real z, const Standard_Real w);
111   void Set (const gp_Quaternion& theQuaternion);
113   Standard_Real X() const;
115   Standard_Real Y() const;
117   Standard_Real Z() const;
119   Standard_Real W() const;
121   //! Make identity quaternion (zero-rotation)
122   void SetIdent();
124   //! Reverse direction of rotation (conjugate quaternion)
125   void Reverse();
127   //! Return rotation with reversed direction (conjugated quaternion)
130   //! Inverts quaternion (both rotation direction and norm)
131   void Invert();
133   //! Return inversed quaternion q^-1
136   //! Returns square norm of quaternion
137   Standard_Real SquareNorm() const;
139   //! Returns norm of quaternion
140   Standard_Real Norm() const;
142   //! Scale all components by quaternion by theScale; note that
143   //! rotation is not changed by this operation (except 0-scaling)
144   void Scale (const Standard_Real theScale);
145 void operator *= (const Standard_Real theScale)
146 {
147   Scale(theScale);
148 }
150   //! Returns scaled quaternion
151 Standard_NODISCARD gp_Quaternion Scaled (const Standard_Real theScale) const;
152 Standard_NODISCARD gp_Quaternion operator * (const Standard_Real theScale) const
153 {
154   return Scaled(theScale);
155 }
157   //! Stabilize quaternion length within 1 - 1/4.
158   //! This operation is a lot faster than normalization
159   //! and preserve length goes to 0 or infinity
160   Standard_EXPORT void StabilizeLength();
162   //! Scale quaternion that its norm goes to 1.
163   //! The appearing of 0 magnitude or near is a error,
164   //! so we can be sure that can divide by magnitude
165   Standard_EXPORT void Normalize();
167   //! Returns quaternion scaled so that its norm goes to 1.
170   //! Returns quaternion with all components negated.
171   //! Note that this operation does not affect neither
172   //! rotation operator defined by quaternion nor its norm.
174 Standard_NODISCARD gp_Quaternion operator -() const
175 {
176   return Negated();
177 }
179   //! Makes sum of quaternion components; result is "rotations mix"
181 Standard_NODISCARD gp_Quaternion operator + (const gp_Quaternion& theOther) const
182 {
184 }
186   //! Makes difference of quaternion components; result is "rotations mix"
187 Standard_NODISCARD gp_Quaternion Subtracted (const gp_Quaternion& theOther) const;
188 Standard_NODISCARD gp_Quaternion operator - (const gp_Quaternion& theOther) const
189 {
190   return Subtracted(theOther);
191 }
193   //! Multiply function - work the same as Matrices multiplying.
194   //! qq' = (cross(v,v') + wv' + w'v, ww' - dot(v,v'))
195   //! Result is rotation combination: q' than q (here q=this, q'=theQ).
196   //! Notices than:
197   //! qq' != q'q;
198   //! qq^-1 = q;
199 Standard_NODISCARD gp_Quaternion Multiplied (const gp_Quaternion& theOther) const;
200 Standard_NODISCARD gp_Quaternion operator * (const gp_Quaternion& theOther) const
201 {
202   return Multiplied(theOther);
203 }
205   //! Adds componnets of other quaternion; result is "rotations mix"
206   void Add (const gp_Quaternion& theOther);
207 void operator += (const gp_Quaternion& theOther)
208 {
210 }
212   //! Subtracts componnets of other quaternion; result is "rotations mix"
213   void Subtract (const gp_Quaternion& theOther);
214 void operator -= (const gp_Quaternion& theOther)
215 {
216   Subtract(theOther);
217 }
219   //! Adds rotation by multiplication
220   void Multiply (const gp_Quaternion& theOther);
221 void operator *= (const gp_Quaternion& theOther)
222 {
223   Multiply(theOther);
224 }
226   //! Computes inner product / scalar product / Dot
227   Standard_Real Dot (const gp_Quaternion& theOther) const;
229   //! Return rotation angle from -PI to PI
230   Standard_EXPORT Standard_Real GetRotationAngle() const;
232   //! Rotates vector by quaternion as rotation operator
233   Standard_EXPORT gp_Vec Multiply (const gp_Vec& theVec) const;
234 gp_Vec operator * (const gp_Vec& theVec) const
235 {
236   return Multiply(theVec);
237 }
242 protected:
248 private:
252   Standard_Real x;
253   Standard_Real y;
254   Standard_Real z;
255   Standard_Real w;
258 };
261 #include <gp_Quaternion.lxx>