quaternion.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2019 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "quaternion.H"
30 #include "IOstreams.H"
31 #include "StringStream.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
37 
40 ({
41  // Proper Euler angles
42  { eulerOrder::XZX, "xzx" },
43  { eulerOrder::XYX, "xyx" },
44  { eulerOrder::YXY, "yxy" },
45  { eulerOrder::YZY, "yzy" },
46  { eulerOrder::ZYZ, "zyz" },
47  { eulerOrder::ZXZ, "zxz" },
48 
49  // Tait-Bryan angles
50  { eulerOrder::XZY, "xzy" },
51  { eulerOrder::XYZ, "xyz" },
52  { eulerOrder::YXZ, "yxz" },
53  { eulerOrder::YZX, "yzx" },
54  { eulerOrder::ZYX, "zyx" },
55  { eulerOrder::ZXY, "zxy" },
56 });
57 
58 
59 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
60 
62 {
63  is >> *this;
64 }
65 
66 
67 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
68 
70 {
71  OStringStream buf;
72  buf << '(' << q.w() << ',' << q.v() << ')';
73  return buf.str();
74 }
75 
76 
78 (
79  const quaternion& qa,
80  const quaternion& qb,
81  const scalar t
82 )
83 {
84  label sign = 1;
85 
86  if ((qa & qb) < 0)
87  {
88  sign = -1;
89  }
90 
91  return qa*pow((inv(qa)*sign*qb), t);
92 }
93 
94 
96 (
97  const UList<quaternion>& qs,
98  const UList<scalar> w
99 )
100 {
101  quaternion qa(w[0]*qs[0]);
102 
103  for (label i=1; i<qs.size(); i++)
104  {
105  // Invert quaternion if it has the opposite sign to the average
106  if ((qa & qs[i]) > 0)
107  {
108  qa += w[i]*qs[i];
109  }
110  else
111  {
112  qa -= w[i]*qs[i];
113  }
114  }
115 
116  return qa;
117 }
118 
119 
121 {
122  const scalar magV = mag(q.v());
123 
124  if (magV == 0)
125  {
126  return quaternion(1, Zero);
127  }
128 
129  const scalar expW = exp(q.w());
130 
131  return quaternion
132  (
133  expW*cos(magV),
134  expW*sin(magV)*q.v()/magV
135  );
136 }
137 
138 
139 Foam::quaternion Foam::pow(const quaternion& q, const label power)
140 {
141  const scalar magQ = mag(q);
142  const scalar magV = mag(q.v());
143 
144  quaternion powq(q.v());
145 
146  if (magV != 0 && magQ != 0)
147  {
148  powq /= magV;
149  powq *= power*acos(q.w()/magQ);
150  }
151 
152  return pow(magQ, power)*exp(powq);
153 }
154 
155 
156 Foam::quaternion Foam::pow(const quaternion& q, const scalar power)
157 {
158  const scalar magQ = mag(q);
159  const scalar magV = mag(q.v());
160 
161  quaternion powq(q.v());
162 
163  if (magV != 0 && magQ != 0)
164  {
165  powq /= magV;
166  powq *= power*acos(q.w()/magQ);
167  }
168 
169  return pow(magQ, power)*exp(powq);
170 }
171 
172 
173 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
174 
176 {
177  is.readBegin("quaternion");
178  is >> q.w() >> q.v();
179  is.readEnd("quaternion");
180 
181  is.check(FUNCTION_NAME);
182  return is;
183 }
184 
185 
187 {
189  << q.w() << token::SPACE << q.v()
190  << token::END_LIST;
191 
192  return os;
193 }
194 
195 
196 // ************************************************************************* //
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:57
IOstreams.H
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
Foam::quaternion::v
const vector & v() const
Vector part of the quaternion ( = axis of rotation)
Definition: quaternionI.H:291
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::slerp
quaternion slerp(const quaternion &qa, const quaternion &qb, const scalar t)
Spherical linear interpolation of quaternions.
Definition: quaternion.C:78
quaternion.H
Foam::sin
dimensionedScalar sin(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:264
StringStream.H
Input/output from string buffers.
Foam::quaternion::I
static const quaternion I
Definition: quaternion.H:126
Foam::operator>>
Istream & operator>>(Istream &, directionInfo &)
Definition: directionInfo.C:230
Foam::exp
dimensionedScalar exp(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:261
Foam::Istream::readEnd
bool readEnd(const char *funcName)
End read of data chunk, ends with ')'.
Definition: Istream.C:129
Foam::quaternion::w
scalar w() const
Scalar part of the quaternion ( = cos(theta/2) for rotation)
Definition: quaternionI.H:285
Foam::sign
dimensionedScalar sign(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:166
Foam::quaternion::quaternion
quaternion()=default
Default construct.
Foam::quaternion
Quaternion class used to perform rotations in 3D space.
Definition: quaternion.H:56
Foam::Istream::readBegin
bool readBegin(const char *funcName)
Begin read of data chunk, starts with '('.
Definition: Istream.C:111
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:83
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::inv
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
Definition: dimensionedSphericalTensor.C:73
Foam::pow
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Definition: dimensionedScalar.C:75
Foam::IOstream::check
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:58
os
OBJstream os(runTime.globalPath()/outputName)
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::Detail::StringStreamAllocator::str
Foam::string str() const
Get the string - as Foam::string rather than std::string.
Definition: StringStream.H:88
Foam::quaternion::eulerOrderNames
static const Enum< eulerOrder > eulerOrderNames
The names for Euler-angle rotation order.
Definition: quaternion.H:112
Foam::OStringStream
Output to string buffer, using a OSstream. Always UNCOMPRESSED.
Definition: StringStream.H:227
Foam::acos
dimensionedScalar acos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:268
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::token::SPACE
Space [isspace].
Definition: token.H:125
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:295
Foam::token::END_LIST
End list [isseparator].
Definition: token.H:156
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::quaternion::zero
static const quaternion zero
Definition: quaternion.H:125
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::token::BEGIN_LIST
Begin list [isseparator].
Definition: token.H:155
Foam::average
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:328
Foam::cos
dimensionedScalar cos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:265