Loading...
Searching...
No Matches
EulerCoordinateRotation.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) 2017-2020 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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
30#include "unitConversion.H"
32
33// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34
35namespace Foam
37namespace coordinateRotations
38{
39
41
42 // Standard short name
44 (
46 euler,
48 euler
49 );
50
51 // Long name - Compat 1806
53 (
55 euler,
57 euler,
58 EulerRotation,
59 1806
60 );
62} // End namespace coordinateRotations
63} // End namespace Foam
64
65
66// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
67
69(
70 const eulerOrder order,
71 const vector& angles,
72 bool degrees
73)
74{
75 scalar angle1(angles.x()); // Rotation #1
76 scalar angle2(angles.y()); // Rotation #2
77 scalar angle3(angles.z()); // Rotation #3
78
79 if (degrees)
80 {
81 angle1 *= degToRad();
82 angle2 *= degToRad();
83 angle3 *= degToRad();
84 }
85
86 const scalar c1(cos(angle1)); const scalar s1(sin(angle1));
87 const scalar c2(cos(angle2)); const scalar s2(sin(angle2));
88 const scalar c3(cos(angle3)); const scalar s3(sin(angle3));
89
90 // https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
91
92 switch (order)
93 {
94 // Proper Euler angles
95
96 case eulerOrder::XZX: // X1-Z2-X3 rotation
97 {
98 return tensor
99 (
100 ( c2 ), ( -c3*s2 ), ( s2*s3 ),
101 ( c1*s2 ), ( c1*c2*c3 - s1*s3 ), ( -c3*s1 - c1*c2*s3 ),
102 ( s1*s2 ), ( c1*s3 + c2*c3*s1 ), ( c1*c3 - c2*s1*s3 )
103 );
104 break;
105 }
106
107 case eulerOrder::XYX: // X1-Y2-X3 rotation
108 {
109 return tensor
110 (
111 ( c2 ), ( s2*s3 ), ( c3*s2 ),
112 ( s1*s2 ), ( c1*c3 - c2*s1*s3 ), ( -c1*s3 - c2*c3*s1 ),
113 ( -c1*s2 ), ( c3*s1 + c1*c2*s3 ), ( c1*c2*c3 - s1*s3 )
114 );
115 break;
116 }
117
118 case eulerOrder::YXY: // Y1-X2-Y3 rotation
119 {
120 return tensor
121 (
122 ( c1*c3 - c2*s1*s3 ), ( s1*s2 ), ( c1*s3 + c2*c3*s1 ),
123 ( s2*s3 ), ( c2 ), ( -c3*s2 ),
124 ( -c3*s1 -c1*c2*s3 ), ( c1*s2 ), ( c1*c2*c3 - s1*s3 )
125 );
126 break;
127 }
128
129 case eulerOrder::YZY: // Y1-Z2-Y3 rotation
130 {
131 return tensor
132 (
133 ( c1*c2*c3 - s1*s3 ), ( -c1*s2 ), ( c3*s1 + c1*c2*s3 ),
134 ( c3*s2 ), ( c2 ), ( s2*s3 ),
135 (-c1*s3 - c2*c3*s1 ), ( s1*s2 ), ( c1*c3 - c2*s1*s3 )
136 );
137 break;
138 }
139
140 case eulerOrder::ZYZ: // Z1-Y2-Z3 rotation
141 {
142 return tensor
143 (
144 ( c1*c2*c3 - s1*s3 ), ( -c3*s1 - c1*c2*s3 ), ( c1*s2 ),
145 ( c1*s3 + c2*c3*s1 ), ( c1*c3 - c2*s1*s3 ), ( s1*s2 ),
146 ( -c3*s2 ), ( s2*s3 ), ( c2 )
147 );
148 break;
149 }
150
151 case eulerOrder::ZXZ: // Z1-X2-Z3 rotation
152 {
153 return tensor
154 (
155 ( c1*c3 - c2*s1*s3 ), ( -c1*s3 - c2*c3*s1 ), ( s1*s2 ),
156 ( c3*s1 + c1*c2*s3 ), ( c1*c2*c3 - s1*s3 ), ( -c1*s2 ),
157 ( s2*s3 ), ( c3*s2 ), ( c2 )
158 );
159 break;
160 }
161
162
163 // Tait-Bryan angles
164
165 case eulerOrder::XZY: // X1-Z2-Y3 rotation
166 {
167 return tensor
168 (
169 ( c2*c3 ), ( -s2 ), ( c2*s3 ),
170 ( s1*s3 + c1*c3*s2 ), ( c1*c2 ), ( c1*s2*s3 - c3*s1 ),
171 ( c3*s1*s2 - c1*s3 ), ( c2*s1 ), ( c1*c3 + s1*s2*s3 )
172 );
173 break;
174 }
175
176 case eulerOrder::XYZ: // X1-Y2-Z3 rotation
177 {
178 return tensor
179 (
180 ( c2*c3 ), ( -c2*s3 ), ( s2 ),
181 ( c1*s3 + c3*s1*s2 ), ( c1*c3 - s1*s2*s3 ), ( -c2*s1 ),
182 ( s1*s3 - c1*c3*s2 ), ( c3*s1 + c1*s2*s3 ), ( c1*c2 )
183 );
184 break;
185 }
186
187 case eulerOrder::YXZ: // Y1-X2-Z3 rotation
188 {
189 return tensor
190 (
191 ( c1*c3 + s1*s2*s3 ), ( c3*s1*s2 - c1*s3 ), ( c2*s1 ),
192 ( c2*s3 ), ( c2*c3 ), ( -s2 ),
193 ( c1*s2*s3 - c3*s1 ), ( c1*c3*s2 + s1*s3 ), ( c1*c2 )
194 );
195 break;
196 }
197
198 case eulerOrder::YZX: // Y1-Z2-X3 rotation
199 {
200 return tensor
201 (
202 ( c1*c2 ), ( s1*s3 - c1*c3*s2 ), ( c3*s1 + c1*s2*s3 ),
203 ( s2 ), ( c2*c3 ), ( -c2*s3 ),
204 ( -c2*s1 ), ( c1*s3 + c3*s1*s2 ), ( c1*c3 - s1*s2*s3 )
205 );
206 break;
207 }
208
209 case eulerOrder::ZYX: // Z1-Y2-X3 rotation
210 {
211 return tensor
212 (
213 ( c1*c2 ), ( c1*s2*s3 - c3*s1 ), ( s1*s3 + c1*c3*s2 ),
214 ( c2*s1 ), ( c1*c3 + s1*s2*s3 ), ( c3*s1*s2 - c1*s3 ),
215 ( -s2 ), ( c2*s3 ), ( c2*c3 )
216 );
217 break;
218 }
219
220 case eulerOrder::ZXY: // Z1-X2-Y3 rotation
221 {
222 return tensor
223 (
224 ( c1*c3 - s1*s2*s3 ), ( -c2*s1 ), ( c1*s3 + c3*s1*s2 ),
225 ( c3*s1 + c1*s2*s3 ), ( c1*c2 ), ( s1*s3 - c1*c3*s2 ),
226 ( -c2*s3 ), ( s2 ), ( c2*c3 )
227 );
228 break;
229 }
230
231 default:
233 << "Unknown euler rotation order "
234 << int(order) << abort(FatalError);
235 }
236
237 return sphericalTensor::I; // identity rotation
238}
239
240
242(
243 const vector& angles,
244 bool degrees
245)
247 return rotation(eulerOrder::ZXZ, angles, degrees);
248}
249
250
251// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
252
254:
256 angles_(Zero),
257 degrees_(true),
258 order_(eulerOrder::ZXZ)
259{}
260
261
263:
265 angles_(crot.angles_),
266 degrees_(crot.degrees_),
267 order_(crot.order_)
268{}
269
270
272(
273 const vector& angles,
274 bool degrees
275)
276:
278 angles_(angles),
279 degrees_(degrees),
280 order_(eulerOrder::ZXZ)
281{}
282
283
285(
286 scalar angle1,
287 scalar angle2,
288 scalar angle3,
289 bool degrees
290)
291:
293 angles_(angle1, angle2, angle3),
294 degrees_(degrees),
295 order_(eulerOrder::ZXZ)
296{}
297
298
300:
302 angles_(dict.get<vector>("angles")),
303 degrees_(dict.getOrDefault("degrees", true)),
304 order_
305 (
306 quaternion::eulerOrderNames.getOrDefault
307 (
308 "order",
309 dict,
310 quaternion::eulerOrder::ZXZ
312 )
313{}
314
315
316// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
317
319{
320 angles_ = Zero;
321 degrees_ = true;
322}
323
326{
327 return euler::rotation(order_, angles_, degrees_);
328}
329
332{
333 os << "euler-angles(" << (degrees_ ? "deg" : "rad") << "): " << angles_;
334}
335
336
338(
339 const word& keyword,
340 Ostream& os
341) const
342{
343 os.beginBlock(keyword);
344
345 os.writeEntry("type", type());
346 os.writeEntry("angles", angles_);
347 if (!degrees_)
348 {
349 os.writeEntry("degrees", "false");
350 }
351
352 // writeEntryIfDifferent, but with enumerated name
353 if (order_ != eulerOrder::ZXZ)
354 {
355 os.writeEntry("order", quaternion::eulerOrderNames[order_]);
356 }
357
358 os.endBlock();
359}
360
361
362// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Macros for easy insertion into run-time selection tables.
#define addAliasToRunTimeSelectionTable(baseType, thisType, argNames, lookup, other, ver)
Add lookup alias for runTime selection.
#define addNamedToRunTimeSelectionTable(baseType, thisType, argNames, lookupName)
Add to construction table with 'lookupName' as the key.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
static const SphericalTensor I
const Cmpt & x() const noexcept
Access to the vector x component.
Definition Vector.H:135
const Cmpt & z() const noexcept
Access to the vector z component.
Definition Vector.H:145
const Cmpt & y() const noexcept
Access to the vector y component.
Definition Vector.H:140
User specification of a coordinate rotation.
A coordinateRotation defined in the z-x-z (intrinsic) Euler convention.
static tensor rotation(const vector &angles, bool degrees=false)
Rotation tensor calculated for the intrinsic Euler angles in z-x-z order.
virtual tensor R() const
The rotation tensor calculated for the specified Euler angles.
euler()
Default construct - an identity transform.
quaternion::eulerOrder eulerOrder
Euler-angle rotation order.
virtual void write(Ostream &os) const
Write information.
virtual void writeEntry(const word &keyword, Ostream &os) const
Write dictionary entry.
virtual void clear()
Reset specification.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
Quaternion class used to perform rotations in 3D space.
Definition quaternion.H:54
static const Enum< eulerOrder > eulerOrderNames
The names for Euler-angle and Tait-Bryan angles, including "rollPitchYaw" and "yawPitchRoll" aliases.
Definition quaternion.H:132
A class for handling words, derived from Foam::string.
Definition word.H:66
#define defineTypeName(Type)
Define the typeName.
Definition className.H:113
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
OBJstream os(runTime.globalPath()/outputName)
Namespace for coordinate system rotations.
Namespace for OpenFOAM.
dimensionedScalar sin(const dimensionedScalar &ds)
Tensor< scalar > tensor
Definition symmTensor.H:57
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition POSIX.C:801
constexpr scalar degToRad() noexcept
Multiplication factor for degrees to radians conversion.
errorManip< error > abort(error &err)
Definition errorManip.H:139
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
Vector< scalar > vector
Definition vector.H:57
dimensionedScalar cos(const dimensionedScalar &ds)
dictionary dict
Unit conversion functions.