open-space-toolkit-mathematics 4.5.3__py310-none-manylinux2014_x86_64.whl → 4.5.4__py310-none-manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of open-space-toolkit-mathematics might be problematic. Click here for more details.
- {open_space_toolkit_mathematics-4.5.3.dist-info → open_space_toolkit_mathematics-4.5.4.dist-info}/METADATA +1 -1
- {open_space_toolkit_mathematics-4.5.3.dist-info → open_space_toolkit_mathematics-4.5.4.dist-info}/RECORD +17 -17
- ostk/mathematics/OpenSpaceToolkitMathematicsPy.cpython-310-x86_64-linux-gnu.so +0 -0
- ostk/mathematics/curve_fitting/__init__.pyi +97 -7
- ostk/mathematics/curve_fitting/interpolator.pyi +204 -16
- ostk/mathematics/geometry/__init__.pyi +364 -32
- ostk/mathematics/geometry/d2/__init__.pyi +560 -48
- ostk/mathematics/geometry/d2/object.pyi +1524 -126
- ostk/mathematics/geometry/d3/__init__.pyi +772 -80
- ostk/mathematics/geometry/d3/object.pyi +3164 -250
- ostk/mathematics/geometry/d3/transformation/rotation.pyi +1007 -91
- ostk/mathematics/libopen-space-toolkit-mathematics.so.4 +0 -0
- ostk/mathematics/object.pyi +292 -22
- ostk/mathematics/solver.pyi +220 -16
- {open_space_toolkit_mathematics-4.5.3.dist-info → open_space_toolkit_mathematics-4.5.4.dist-info}/WHEEL +0 -0
- {open_space_toolkit_mathematics-4.5.3.dist-info → open_space_toolkit_mathematics-4.5.4.dist-info}/top_level.txt +0 -0
- {open_space_toolkit_mathematics-4.5.3.dist-info → open_space_toolkit_mathematics-4.5.4.dist-info}/zip-safe +0 -0
|
@@ -50,7 +50,20 @@ class EulerAngle:
|
|
|
50
50
|
__hash__: typing.ClassVar[None] = None
|
|
51
51
|
@staticmethod
|
|
52
52
|
def quaternion(quaternion: Quaternion, axis_sequence: typing.Any) -> EulerAngle:
|
|
53
|
-
|
|
53
|
+
"""
|
|
54
|
+
Create Euler angles from a quaternion with specified axis sequence.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
quaternion (Quaternion): The quaternion to convert.
|
|
58
|
+
axis_sequence (EulerAngle.AxisSequence): The desired axis sequence.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
EulerAngle: The equivalent Euler angles.
|
|
62
|
+
|
|
63
|
+
Example:
|
|
64
|
+
>>> quat = Quaternion.unit()
|
|
65
|
+
>>> euler = EulerAngle.quaternion(quat, EulerAngle.AxisSequence.XYZ)
|
|
66
|
+
"""
|
|
54
67
|
@staticmethod
|
|
55
68
|
def rotation_matrix(rotation_matrix: RotationMatrix, axis_sequence: typing.Any) -> EulerAngle:
|
|
56
69
|
...
|
|
@@ -59,27 +72,109 @@ class EulerAngle:
|
|
|
59
72
|
...
|
|
60
73
|
@staticmethod
|
|
61
74
|
def undefined() -> EulerAngle:
|
|
62
|
-
|
|
75
|
+
"""
|
|
76
|
+
Create an undefined Euler angle.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
EulerAngle: An undefined Euler angle object.
|
|
80
|
+
|
|
81
|
+
Example:
|
|
82
|
+
>>> undefined_euler = EulerAngle.undefined()
|
|
83
|
+
>>> undefined_euler.is_defined() # False
|
|
84
|
+
"""
|
|
63
85
|
@staticmethod
|
|
64
86
|
def unit() -> EulerAngle:
|
|
65
|
-
|
|
87
|
+
"""
|
|
88
|
+
Create a unit Euler angle (no rotation).
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
EulerAngle: A unit Euler angle representing no rotation.
|
|
92
|
+
|
|
93
|
+
Example:
|
|
94
|
+
>>> unit_euler = EulerAngle.unit()
|
|
95
|
+
>>> unit_euler.is_unitary() # True
|
|
96
|
+
"""
|
|
66
97
|
@staticmethod
|
|
67
98
|
def xyz(phi: typing.Any, theta: typing.Any, psi: typing.Any) -> EulerAngle:
|
|
68
|
-
|
|
99
|
+
"""
|
|
100
|
+
Create Euler angles with XYZ axis sequence.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
phi (Angle): The first rotation angle around X-axis.
|
|
104
|
+
theta (Angle): The second rotation angle around Y-axis.
|
|
105
|
+
psi (Angle): The third rotation angle around Z-axis.
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
EulerAngle: An Euler angle with XYZ sequence.
|
|
109
|
+
|
|
110
|
+
Example:
|
|
111
|
+
>>> euler = EulerAngle.xyz(Angle.degrees(30.0), Angle.degrees(45.0), Angle.degrees(60.0))
|
|
112
|
+
"""
|
|
69
113
|
@staticmethod
|
|
70
114
|
def zxy(phi: typing.Any, theta: typing.Any, psi: typing.Any) -> EulerAngle:
|
|
71
|
-
|
|
115
|
+
"""
|
|
116
|
+
Create Euler angles with ZXY axis sequence.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
phi (Angle): The first rotation angle around Z-axis.
|
|
120
|
+
theta (Angle): The second rotation angle around X-axis.
|
|
121
|
+
psi (Angle): The third rotation angle around Y-axis.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
EulerAngle: An Euler angle with ZXY sequence.
|
|
125
|
+
|
|
126
|
+
Example:
|
|
127
|
+
>>> euler = EulerAngle.zxy(Angle.degrees(30.0), Angle.degrees(45.0), Angle.degrees(60.0))
|
|
128
|
+
"""
|
|
72
129
|
@staticmethod
|
|
73
130
|
def zyx(phi: typing.Any, theta: typing.Any, psi: typing.Any) -> EulerAngle:
|
|
74
|
-
|
|
131
|
+
"""
|
|
132
|
+
Create Euler angles with ZYX axis sequence.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
phi (Angle): The first rotation angle around Z-axis.
|
|
136
|
+
theta (Angle): The second rotation angle around Y-axis.
|
|
137
|
+
psi (Angle): The third rotation angle around X-axis.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
EulerAngle: An Euler angle with ZYX sequence.
|
|
141
|
+
|
|
142
|
+
Example:
|
|
143
|
+
>>> euler = EulerAngle.zyx(Angle.degrees(30.0), Angle.degrees(45.0), Angle.degrees(60.0))
|
|
144
|
+
"""
|
|
75
145
|
def __eq__(self, arg0: EulerAngle) -> bool:
|
|
76
146
|
...
|
|
77
147
|
@typing.overload
|
|
78
148
|
def __init__(self, phi: typing.Any, theta: typing.Any, psi: typing.Any, axis_sequence: typing.Any) -> None:
|
|
79
|
-
|
|
149
|
+
"""
|
|
150
|
+
Create Euler angles from three angle components and axis sequence.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
phi (Angle): The first rotation angle.
|
|
154
|
+
theta (Angle): The second rotation angle.
|
|
155
|
+
psi (Angle): The third rotation angle.
|
|
156
|
+
axis_sequence (EulerAngle.AxisSequence): The axis sequence (XYZ, ZXY, ZYX).
|
|
157
|
+
|
|
158
|
+
Example:
|
|
159
|
+
>>> phi = Angle.degrees(30.0)
|
|
160
|
+
>>> theta = Angle.degrees(45.0)
|
|
161
|
+
>>> psi = Angle.degrees(60.0)
|
|
162
|
+
>>> euler = EulerAngle(phi, theta, psi, EulerAngle.AxisSequence.XYZ)
|
|
163
|
+
"""
|
|
80
164
|
@typing.overload
|
|
81
165
|
def __init__(self, vector: numpy.ndarray[numpy.float64[3, 1]], angle_unit: typing.Any, axis_sequence: typing.Any) -> None:
|
|
82
|
-
|
|
166
|
+
"""
|
|
167
|
+
Create Euler angles from a 3D vector with specified angle unit and axis sequence.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
vector (np.array): Vector containing the three angle values.
|
|
171
|
+
angle_unit (Angle.Unit): The unit of the angles in the vector.
|
|
172
|
+
axis_sequence (EulerAngle.AxisSequence): The axis sequence.
|
|
173
|
+
|
|
174
|
+
Example:
|
|
175
|
+
>>> vector = np.array([30.0, 45.0, 60.0])
|
|
176
|
+
>>> euler = EulerAngle(vector, Angle.Unit.Degree, EulerAngle.AxisSequence.XYZ)
|
|
177
|
+
"""
|
|
83
178
|
def __ne__(self, arg0: EulerAngle) -> bool:
|
|
84
179
|
...
|
|
85
180
|
def __repr__(self) -> str:
|
|
@@ -87,11 +182,43 @@ class EulerAngle:
|
|
|
87
182
|
def __str__(self) -> str:
|
|
88
183
|
...
|
|
89
184
|
def is_defined(self) -> bool:
|
|
90
|
-
|
|
185
|
+
"""
|
|
186
|
+
Check if the Euler angle is defined.
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
bool: True if the Euler angle is defined, False otherwise.
|
|
190
|
+
|
|
191
|
+
Example:
|
|
192
|
+
>>> euler = EulerAngle(phi, theta, psi, EulerAngle.AxisSequence.XYZ)
|
|
193
|
+
>>> euler.is_defined() # True
|
|
194
|
+
"""
|
|
91
195
|
def is_near(self, euler_angle: EulerAngle, angular_tolerance: typing.Any) -> bool:
|
|
92
|
-
|
|
196
|
+
"""
|
|
197
|
+
Check if this Euler angle is near another Euler angle within tolerance.
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
euler_angle (EulerAngle): The Euler angle to compare with.
|
|
201
|
+
angular_tolerance (Angle): The angular tolerance for comparison.
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
bool: True if angles are within tolerance, False otherwise.
|
|
205
|
+
|
|
206
|
+
Example:
|
|
207
|
+
>>> euler1 = EulerAngle(phi1, theta1, psi1, sequence)
|
|
208
|
+
>>> euler2 = EulerAngle(phi2, theta2, psi2, sequence)
|
|
209
|
+
>>> euler1.is_near(euler2, Angle.degrees(1.0))
|
|
210
|
+
"""
|
|
93
211
|
def is_unitary(self) -> bool:
|
|
94
|
-
|
|
212
|
+
"""
|
|
213
|
+
Check if the Euler angle represents a unit rotation.
|
|
214
|
+
|
|
215
|
+
Returns:
|
|
216
|
+
bool: True if the Euler angle is unitary, False otherwise.
|
|
217
|
+
|
|
218
|
+
Example:
|
|
219
|
+
>>> euler = EulerAngle.unit()
|
|
220
|
+
>>> euler.is_unitary() # True
|
|
221
|
+
"""
|
|
95
222
|
@typing.overload
|
|
96
223
|
def to_string(self) -> ostk.core.type.String:
|
|
97
224
|
...
|
|
@@ -99,7 +226,19 @@ class EulerAngle:
|
|
|
99
226
|
def to_string(self, angle_unit: typing.Any) -> ostk.core.type.String:
|
|
100
227
|
...
|
|
101
228
|
def to_vector(self, angle_unit: typing.Any) -> numpy.ndarray[numpy.float64[3, 1]]:
|
|
102
|
-
|
|
229
|
+
"""
|
|
230
|
+
Convert the Euler angle to a 3D vector with specified unit.
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
angle_unit (Angle.Unit): The unit for the output vector angles.
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
Vector3d: A vector containing [phi, theta, psi] in the specified unit.
|
|
237
|
+
|
|
238
|
+
Example:
|
|
239
|
+
>>> euler = EulerAngle(phi, theta, psi, EulerAngle.AxisSequence.XYZ)
|
|
240
|
+
>>> vector = euler.to_vector(Angle.Unit.Degree)
|
|
241
|
+
"""
|
|
103
242
|
@property
|
|
104
243
|
def axis_sequence(self) -> ...:
|
|
105
244
|
...
|
|
@@ -153,37 +292,176 @@ class Quaternion:
|
|
|
153
292
|
__hash__: typing.ClassVar[None] = None
|
|
154
293
|
@staticmethod
|
|
155
294
|
def euler_angle(euler_angle: typing.Any) -> Quaternion:
|
|
156
|
-
|
|
295
|
+
"""
|
|
296
|
+
Create a quaternion from Euler angles.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
euler_angle (EulerAngle): The Euler angles.
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
Quaternion: The quaternion representing the rotation.
|
|
303
|
+
|
|
304
|
+
Example:
|
|
305
|
+
>>> ea = EulerAngle.zyx(Angle.radians(0.1), Angle.radians(0.2), Angle.radians(0.3))
|
|
306
|
+
>>> q = Quaternion.euler_angle(ea)
|
|
307
|
+
"""
|
|
157
308
|
@staticmethod
|
|
158
309
|
def lerp(first_quaternion: Quaternion, second_quaternion: Quaternion, ratio: ostk.core.type.Real) -> Quaternion:
|
|
159
|
-
|
|
310
|
+
"""
|
|
311
|
+
Linear interpolation between two quaternions.
|
|
312
|
+
|
|
313
|
+
Args:
|
|
314
|
+
first_quaternion (Quaternion): The first quaternion.
|
|
315
|
+
second_quaternion (Quaternion): The second quaternion.
|
|
316
|
+
ratio (float): The interpolation ratio (0.0 to 1.0).
|
|
317
|
+
|
|
318
|
+
Returns:
|
|
319
|
+
Quaternion: The interpolated quaternion.
|
|
320
|
+
|
|
321
|
+
Example:
|
|
322
|
+
>>> q1 = Quaternion.unit()
|
|
323
|
+
>>> q2 = Quaternion(0.1, 0.2, 0.3, 0.9, Quaternion.Format.XYZS)
|
|
324
|
+
>>> q_interp = Quaternion.lerp(q1, q2, 0.5)
|
|
325
|
+
"""
|
|
160
326
|
@staticmethod
|
|
161
327
|
def nlerp(first_quaternion: Quaternion, second_quaternion: Quaternion, ratio: ostk.core.type.Real) -> Quaternion:
|
|
162
|
-
|
|
328
|
+
"""
|
|
329
|
+
Normalized linear interpolation between two quaternions.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
first_quaternion (Quaternion): The first quaternion.
|
|
333
|
+
second_quaternion (Quaternion): The second quaternion.
|
|
334
|
+
ratio (float): The interpolation ratio (0.0 to 1.0).
|
|
335
|
+
|
|
336
|
+
Returns:
|
|
337
|
+
Quaternion: The normalized interpolated quaternion.
|
|
338
|
+
|
|
339
|
+
Example:
|
|
340
|
+
>>> q1 = Quaternion.unit()
|
|
341
|
+
>>> q2 = Quaternion(0.1, 0.2, 0.3, 0.9, Quaternion.Format.XYZS)
|
|
342
|
+
>>> q_interp = Quaternion.nlerp(q1, q2, 0.5)
|
|
343
|
+
"""
|
|
163
344
|
@staticmethod
|
|
164
345
|
def parse(string: ostk.core.type.String, format: typing.Any) -> Quaternion:
|
|
165
|
-
|
|
346
|
+
"""
|
|
347
|
+
Parse a quaternion from a string.
|
|
348
|
+
|
|
349
|
+
Args:
|
|
350
|
+
string (str): The string representation of the quaternion.
|
|
351
|
+
format (Quaternion.Format): The format of the quaternion.
|
|
352
|
+
|
|
353
|
+
Returns:
|
|
354
|
+
Quaternion: The parsed quaternion.
|
|
355
|
+
|
|
356
|
+
Example:
|
|
357
|
+
>>> q = Quaternion.parse("[0.0, 0.0, 0.0, 1.0]", Quaternion.Format.XYZS)
|
|
358
|
+
"""
|
|
166
359
|
@staticmethod
|
|
167
360
|
def rotation_matrix(rotation_matrix: typing.Any) -> Quaternion:
|
|
168
|
-
|
|
361
|
+
"""
|
|
362
|
+
Create a quaternion from a rotation matrix.
|
|
363
|
+
|
|
364
|
+
Args:
|
|
365
|
+
rotation_matrix (RotationMatrix): The rotation matrix.
|
|
366
|
+
|
|
367
|
+
Returns:
|
|
368
|
+
Quaternion: The quaternion representing the rotation.
|
|
369
|
+
|
|
370
|
+
Example:
|
|
371
|
+
>>> rm = RotationMatrix.identity()
|
|
372
|
+
>>> q = Quaternion.rotation_matrix(rm)
|
|
373
|
+
"""
|
|
169
374
|
@staticmethod
|
|
170
375
|
def rotation_vector(rotation_vector: typing.Any) -> Quaternion:
|
|
171
|
-
|
|
376
|
+
"""
|
|
377
|
+
Create a quaternion from a rotation vector.
|
|
378
|
+
|
|
379
|
+
Args:
|
|
380
|
+
rotation_vector (RotationVector): The rotation vector.
|
|
381
|
+
|
|
382
|
+
Returns:
|
|
383
|
+
Quaternion: The quaternion representing the rotation.
|
|
384
|
+
|
|
385
|
+
Example:
|
|
386
|
+
>>> rv = RotationVector([0.1, 0.2, 0.3], Angle.radians(1.0))
|
|
387
|
+
>>> q = Quaternion.rotation_vector(rv)
|
|
388
|
+
"""
|
|
172
389
|
@staticmethod
|
|
173
390
|
def shortest_rotation(first_vector: numpy.ndarray[numpy.float64[3, 1]], second_vector: numpy.ndarray[numpy.float64[3, 1]]) -> Quaternion:
|
|
174
|
-
|
|
391
|
+
"""
|
|
392
|
+
Create a quaternion representing the shortest rotation between two vectors.
|
|
393
|
+
|
|
394
|
+
Args:
|
|
395
|
+
first_vector (np.array): The first vector.
|
|
396
|
+
second_vector (np.array): The second vector.
|
|
397
|
+
|
|
398
|
+
Returns:
|
|
399
|
+
Quaternion: The quaternion representing the shortest rotation.
|
|
400
|
+
|
|
401
|
+
Example:
|
|
402
|
+
>>> v1 = np.array([1.0, 0.0, 0.0])
|
|
403
|
+
>>> v2 = np.array([0.0, 1.0, 0.0])
|
|
404
|
+
>>> q = Quaternion.shortest_rotation(v1, v2)
|
|
405
|
+
"""
|
|
175
406
|
@staticmethod
|
|
176
407
|
def slerp(first_quaternion: Quaternion, second_quaternion: Quaternion, ratio: ostk.core.type.Real) -> Quaternion:
|
|
177
|
-
|
|
408
|
+
"""
|
|
409
|
+
Spherical linear interpolation between two quaternions.
|
|
410
|
+
|
|
411
|
+
Args:
|
|
412
|
+
first_quaternion (Quaternion): The first quaternion.
|
|
413
|
+
second_quaternion (Quaternion): The second quaternion.
|
|
414
|
+
ratio (float): The interpolation ratio (0.0 to 1.0).
|
|
415
|
+
|
|
416
|
+
Returns:
|
|
417
|
+
Quaternion: The spherically interpolated quaternion.
|
|
418
|
+
|
|
419
|
+
Example:
|
|
420
|
+
>>> q1 = Quaternion.unit()
|
|
421
|
+
>>> q2 = Quaternion(0.1, 0.2, 0.3, 0.9, Quaternion.Format.XYZS)
|
|
422
|
+
>>> q_interp = Quaternion.slerp(q1, q2, 0.5)
|
|
423
|
+
"""
|
|
178
424
|
@staticmethod
|
|
179
425
|
def undefined() -> Quaternion:
|
|
180
|
-
|
|
426
|
+
"""
|
|
427
|
+
Create an undefined quaternion.
|
|
428
|
+
|
|
429
|
+
Returns:
|
|
430
|
+
Quaternion: An undefined quaternion.
|
|
431
|
+
|
|
432
|
+
Example:
|
|
433
|
+
>>> q = Quaternion.undefined()
|
|
434
|
+
>>> q.is_defined() # False
|
|
435
|
+
"""
|
|
181
436
|
@staticmethod
|
|
182
437
|
def unit() -> Quaternion:
|
|
183
|
-
|
|
438
|
+
"""
|
|
439
|
+
Create a unit quaternion (identity rotation).
|
|
440
|
+
|
|
441
|
+
Returns:
|
|
442
|
+
Quaternion: A unit quaternion.
|
|
443
|
+
|
|
444
|
+
Example:
|
|
445
|
+
>>> q = Quaternion.unit()
|
|
446
|
+
>>> q.is_unitary() # True
|
|
447
|
+
"""
|
|
184
448
|
@staticmethod
|
|
185
449
|
def xyzs(first_component: ostk.core.type.Real, second_component: ostk.core.type.Real, third_component: ostk.core.type.Real, fourth_component: ostk.core.type.Real) -> Quaternion:
|
|
186
|
-
|
|
450
|
+
"""
|
|
451
|
+
Create a quaternion in XYZS format.
|
|
452
|
+
|
|
453
|
+
Args:
|
|
454
|
+
first_component (float): The x component.
|
|
455
|
+
second_component (float): The y component.
|
|
456
|
+
third_component (float): The z component.
|
|
457
|
+
fourth_component (float): The s component.
|
|
458
|
+
|
|
459
|
+
Returns:
|
|
460
|
+
Quaternion: The quaternion in XYZS format.
|
|
461
|
+
|
|
462
|
+
Example:
|
|
463
|
+
>>> q = Quaternion.xyzs(0.0, 0.0, 0.0, 1.0)
|
|
464
|
+
"""
|
|
187
465
|
def __add__(self, arg0: Quaternion) -> Quaternion:
|
|
188
466
|
...
|
|
189
467
|
def __eq__(self, arg0: Quaternion) -> bool:
|
|
@@ -192,16 +470,59 @@ class Quaternion:
|
|
|
192
470
|
...
|
|
193
471
|
@typing.overload
|
|
194
472
|
def __init__(self, first_component: ostk.core.type.Real, second_component: ostk.core.type.Real, third_component: ostk.core.type.Real, fourth_component: ostk.core.type.Real, format: typing.Any) -> None:
|
|
195
|
-
|
|
473
|
+
"""
|
|
474
|
+
Create a quaternion from four components and format.
|
|
475
|
+
|
|
476
|
+
Args:
|
|
477
|
+
first_component (float): First component (x or w depending on format).
|
|
478
|
+
second_component (float): Second component (y or x depending on format).
|
|
479
|
+
third_component (float): Third component (z or y depending on format).
|
|
480
|
+
fourth_component (float): Fourth component (w or z depending on format).
|
|
481
|
+
format (Quaternion.Format): The quaternion format (XYZS or SXYZ).
|
|
482
|
+
|
|
483
|
+
Example:
|
|
484
|
+
>>> q = Quaternion(0.0, 0.0, 0.0, 1.0, Quaternion.Format.XYZS)
|
|
485
|
+
>>> q = Quaternion(1.0, 0.0, 0.0, 0.0, Quaternion.Format.SXYZ)
|
|
486
|
+
"""
|
|
196
487
|
@typing.overload
|
|
197
488
|
def __init__(self, vector: numpy.ndarray[numpy.float64[4, 1]], format: typing.Any) -> None:
|
|
198
|
-
|
|
489
|
+
"""
|
|
490
|
+
Create a quaternion from a 4D vector and format.
|
|
491
|
+
|
|
492
|
+
Args:
|
|
493
|
+
vector (np.array): The 4D vector containing quaternion components.
|
|
494
|
+
format (Quaternion.Format): The quaternion format.
|
|
495
|
+
|
|
496
|
+
Example:
|
|
497
|
+
>>> vector = np.array([0.0, 0.0, 0.0, 1.0])
|
|
498
|
+
>>> q = Quaternion(vector, Quaternion.Format.XYZS)
|
|
499
|
+
"""
|
|
199
500
|
@typing.overload
|
|
200
501
|
def __init__(self, vector_part: numpy.ndarray[numpy.float64[3, 1]], scalar_part: ostk.core.type.Real) -> None:
|
|
201
|
-
|
|
502
|
+
"""
|
|
503
|
+
Create a quaternion from vector and scalar parts.
|
|
504
|
+
|
|
505
|
+
Args:
|
|
506
|
+
vector_part (np.array): The vector part (x, y, z components).
|
|
507
|
+
scalar_part (float): The scalar part (s component).
|
|
508
|
+
|
|
509
|
+
Example:
|
|
510
|
+
>>> vector_part = np.array([0.0, 0.0, 0.0])
|
|
511
|
+
>>> scalar_part = 1.0
|
|
512
|
+
>>> q = Quaternion(vector_part, scalar_part)
|
|
513
|
+
"""
|
|
202
514
|
@typing.overload
|
|
203
515
|
def __init__(self, quaternion: Quaternion) -> None:
|
|
204
|
-
|
|
516
|
+
"""
|
|
517
|
+
Create a quaternion by copying another quaternion.
|
|
518
|
+
|
|
519
|
+
Args:
|
|
520
|
+
quaternion (Quaternion): The quaternion to copy.
|
|
521
|
+
|
|
522
|
+
Example:
|
|
523
|
+
>>> original = Quaternion(0.0, 0.0, 0.0, 1.0, Quaternion.Format.XYZS)
|
|
524
|
+
>>> copy = Quaternion(original)
|
|
525
|
+
"""
|
|
205
526
|
@typing.overload
|
|
206
527
|
def __mul__(self, arg0: Quaternion) -> Quaternion:
|
|
207
528
|
...
|
|
@@ -224,103 +545,479 @@ class Quaternion:
|
|
|
224
545
|
def __truediv__(self, arg0: Quaternion) -> Quaternion:
|
|
225
546
|
...
|
|
226
547
|
def angular_difference_with(self, quaternion: Quaternion) -> ...:
|
|
227
|
-
|
|
548
|
+
"""
|
|
549
|
+
Compute the angular difference with another quaternion.
|
|
550
|
+
|
|
551
|
+
Args:
|
|
552
|
+
quaternion (Quaternion): The quaternion to compare with.
|
|
553
|
+
|
|
554
|
+
Returns:
|
|
555
|
+
Angle: The angular difference.
|
|
556
|
+
|
|
557
|
+
Example:
|
|
558
|
+
>>> q1 = Quaternion.unit()
|
|
559
|
+
>>> q2 = Quaternion(0.1, 0.2, 0.3, 0.9, Quaternion.Format.XYZS)
|
|
560
|
+
>>> angle = q1.angular_difference_with(q2)
|
|
561
|
+
"""
|
|
228
562
|
def conjugate(self) -> None:
|
|
229
|
-
|
|
563
|
+
"""
|
|
564
|
+
Conjugate the quaternion in-place.
|
|
565
|
+
|
|
566
|
+
Example:
|
|
567
|
+
>>> q = Quaternion(1.0, 2.0, 3.0, 4.0, Quaternion.Format.XYZS)
|
|
568
|
+
>>> q.conjugate()
|
|
569
|
+
"""
|
|
230
570
|
def cross_multiply(self, quaternion: Quaternion) -> Quaternion:
|
|
231
|
-
|
|
571
|
+
"""
|
|
572
|
+
Perform cross multiplication with another quaternion.
|
|
573
|
+
|
|
574
|
+
Args:
|
|
575
|
+
quaternion (Quaternion): The quaternion to multiply with.
|
|
576
|
+
|
|
577
|
+
Returns:
|
|
578
|
+
Quaternion: The result of cross multiplication.
|
|
579
|
+
|
|
580
|
+
Example:
|
|
581
|
+
>>> q1 = Quaternion.unit()
|
|
582
|
+
>>> q2 = Quaternion(0.1, 0.2, 0.3, 0.9, Quaternion.Format.XYZS)
|
|
583
|
+
>>> result = q1.cross_multiply(q2)
|
|
584
|
+
"""
|
|
232
585
|
def dot_multiply(self, quaternion: Quaternion) -> Quaternion:
|
|
233
|
-
|
|
586
|
+
"""
|
|
587
|
+
Perform dot multiplication with another quaternion.
|
|
588
|
+
|
|
589
|
+
Args:
|
|
590
|
+
quaternion (Quaternion): The quaternion to multiply with.
|
|
591
|
+
|
|
592
|
+
Returns:
|
|
593
|
+
Quaternion: The result of dot multiplication.
|
|
594
|
+
|
|
595
|
+
Example:
|
|
596
|
+
>>> q1 = Quaternion.unit()
|
|
597
|
+
>>> q2 = Quaternion(0.1, 0.2, 0.3, 0.9, Quaternion.Format.XYZS)
|
|
598
|
+
>>> result = q1.dot_multiply(q2)
|
|
599
|
+
"""
|
|
234
600
|
def dot_product(self, quaternion: Quaternion) -> ostk.core.type.Real:
|
|
235
|
-
|
|
601
|
+
"""
|
|
602
|
+
Compute the dot product with another quaternion.
|
|
603
|
+
|
|
604
|
+
Args:
|
|
605
|
+
quaternion (Quaternion): The quaternion to compute dot product with.
|
|
606
|
+
|
|
607
|
+
Returns:
|
|
608
|
+
float: The dot product result.
|
|
609
|
+
|
|
610
|
+
Example:
|
|
611
|
+
>>> q1 = Quaternion.unit()
|
|
612
|
+
>>> q2 = Quaternion(0.1, 0.2, 0.3, 0.9, Quaternion.Format.XYZS)
|
|
613
|
+
>>> dot = q1.dot_product(q2)
|
|
614
|
+
"""
|
|
236
615
|
def exp(self) -> Quaternion:
|
|
237
|
-
|
|
616
|
+
"""
|
|
617
|
+
Compute the exponential of the quaternion.
|
|
618
|
+
|
|
619
|
+
Returns:
|
|
620
|
+
Quaternion: The exponential of the quaternion.
|
|
621
|
+
|
|
622
|
+
Example:
|
|
623
|
+
>>> q = Quaternion(0.1, 0.2, 0.3, 0.0, Quaternion.Format.XYZS)
|
|
624
|
+
>>> exp_q = q.exp()
|
|
625
|
+
"""
|
|
238
626
|
def get_scalar_part(self) -> ostk.core.type.Real:
|
|
239
|
-
|
|
627
|
+
"""
|
|
628
|
+
Get the scalar part of the quaternion.
|
|
629
|
+
|
|
630
|
+
Returns:
|
|
631
|
+
float: The scalar part.
|
|
632
|
+
|
|
633
|
+
Example:
|
|
634
|
+
>>> q = Quaternion(0.0, 0.0, 0.0, 1.0, Quaternion.Format.XYZS)
|
|
635
|
+
>>> q.get_scalar_part() # 1.0
|
|
636
|
+
"""
|
|
240
637
|
def get_vector_part(self) -> numpy.ndarray[numpy.float64[3, 1]]:
|
|
241
|
-
|
|
638
|
+
"""
|
|
639
|
+
Get the vector part of the quaternion.
|
|
640
|
+
|
|
641
|
+
Returns:
|
|
642
|
+
Vector3d: The vector part.
|
|
643
|
+
"""
|
|
242
644
|
def inverse(self) -> None:
|
|
243
|
-
|
|
645
|
+
"""
|
|
646
|
+
Invert the quaternion in-place.
|
|
647
|
+
|
|
648
|
+
Example:
|
|
649
|
+
>>> q = Quaternion.unit()
|
|
650
|
+
>>> q.inverse()
|
|
651
|
+
"""
|
|
244
652
|
def is_defined(self) -> bool:
|
|
245
|
-
|
|
653
|
+
"""
|
|
654
|
+
Check if the quaternion is defined.
|
|
655
|
+
|
|
656
|
+
Returns:
|
|
657
|
+
bool: True if the quaternion is defined, False otherwise.
|
|
658
|
+
"""
|
|
246
659
|
def is_near(self, quaternion: Quaternion, angular_tolerance: typing.Any) -> bool:
|
|
247
|
-
|
|
660
|
+
"""
|
|
661
|
+
Check if the quaternion is near another quaternion.
|
|
662
|
+
|
|
663
|
+
Returns:
|
|
664
|
+
bool: True if the quaternion is near another quaternion, False otherwise.
|
|
665
|
+
"""
|
|
248
666
|
def is_unitary(self, norm_tolerance: ostk.core.type.Real = ...) -> bool:
|
|
249
|
-
|
|
667
|
+
"""
|
|
668
|
+
Check if the quaternion is unitary.
|
|
669
|
+
|
|
670
|
+
Returns:
|
|
671
|
+
bool: True if the quaternion is unitary, False otherwise.
|
|
672
|
+
"""
|
|
250
673
|
def log(self) -> Quaternion:
|
|
251
|
-
|
|
674
|
+
"""
|
|
675
|
+
Compute the natural logarithm of the quaternion.
|
|
676
|
+
|
|
677
|
+
Returns:
|
|
678
|
+
Quaternion: The natural logarithm of the quaternion.
|
|
679
|
+
|
|
680
|
+
Example:
|
|
681
|
+
>>> q = Quaternion.unit()
|
|
682
|
+
>>> log_q = q.log()
|
|
683
|
+
"""
|
|
252
684
|
def norm(self) -> ostk.core.type.Real:
|
|
253
|
-
|
|
685
|
+
"""
|
|
686
|
+
Compute the norm (magnitude) of the quaternion.
|
|
687
|
+
|
|
688
|
+
Returns:
|
|
689
|
+
float: The norm of the quaternion.
|
|
690
|
+
|
|
691
|
+
Example:
|
|
692
|
+
>>> q = Quaternion(1.0, 2.0, 3.0, 4.0, Quaternion.Format.XYZS)
|
|
693
|
+
>>> magnitude = q.norm()
|
|
694
|
+
"""
|
|
254
695
|
def normalize(self) -> None:
|
|
255
|
-
|
|
696
|
+
"""
|
|
697
|
+
Normalize the quaternion in-place.
|
|
698
|
+
|
|
699
|
+
Example:
|
|
700
|
+
>>> q = Quaternion(1.0, 1.0, 1.0, 1.0, Quaternion.Format.XYZS)
|
|
701
|
+
>>> q.normalize()
|
|
702
|
+
"""
|
|
256
703
|
def pow(self, value: ostk.core.type.Real) -> Quaternion:
|
|
257
|
-
|
|
704
|
+
"""
|
|
705
|
+
Raise the quaternion to a power.
|
|
706
|
+
|
|
707
|
+
Args:
|
|
708
|
+
value (float): The exponent.
|
|
709
|
+
|
|
710
|
+
Returns:
|
|
711
|
+
Quaternion: The quaternion raised to the power.
|
|
712
|
+
|
|
713
|
+
Example:
|
|
714
|
+
>>> q = Quaternion.unit()
|
|
715
|
+
>>> powered = q.pow(2.0)
|
|
716
|
+
"""
|
|
258
717
|
def rectify(self) -> None:
|
|
259
|
-
|
|
718
|
+
"""
|
|
719
|
+
Rectify the quaternion in-place (ensure positive scalar part).
|
|
720
|
+
|
|
721
|
+
Example:
|
|
722
|
+
>>> q = Quaternion(0.0, 0.0, 0.0, -1.0, Quaternion.Format.XYZS)
|
|
723
|
+
>>> q.rectify()
|
|
724
|
+
"""
|
|
260
725
|
def rotate_vector(self, vector: numpy.ndarray[numpy.float64[3, 1]], norm_tolerance: ostk.core.type.Real = ...) -> numpy.ndarray[numpy.float64[3, 1]]:
|
|
261
|
-
|
|
726
|
+
"""
|
|
727
|
+
Rotate a vector using this quaternion.
|
|
728
|
+
|
|
729
|
+
Args:
|
|
730
|
+
vector (np.array): The 3D vector to rotate.
|
|
731
|
+
norm_tolerance (float, optional): Tolerance for normalization check.
|
|
732
|
+
|
|
733
|
+
Returns:
|
|
734
|
+
Vector3d: The rotated vector.
|
|
735
|
+
|
|
736
|
+
Example:
|
|
737
|
+
>>> q = Quaternion.unit()
|
|
738
|
+
>>> vector = np.array([1.0, 0.0, 0.0])
|
|
739
|
+
>>> rotated = q.rotate_vector(vector)
|
|
740
|
+
"""
|
|
262
741
|
def s(self) -> ostk.core.type.Real:
|
|
263
|
-
|
|
742
|
+
"""
|
|
743
|
+
Get the s-coordinate of the quaternion.
|
|
744
|
+
|
|
745
|
+
Returns:
|
|
746
|
+
float: The s-coordinate.
|
|
747
|
+
"""
|
|
264
748
|
def to_conjugate(self) -> Quaternion:
|
|
265
|
-
|
|
749
|
+
"""
|
|
750
|
+
Get the conjugate of the quaternion.
|
|
751
|
+
|
|
752
|
+
Returns:
|
|
753
|
+
Quaternion: The conjugate quaternion.
|
|
754
|
+
|
|
755
|
+
Example:
|
|
756
|
+
>>> q = Quaternion(1.0, 2.0, 3.0, 4.0, Quaternion.Format.XYZS)
|
|
757
|
+
>>> conjugate = q.to_conjugate()
|
|
758
|
+
"""
|
|
266
759
|
def to_inverse(self) -> Quaternion:
|
|
267
|
-
|
|
760
|
+
"""
|
|
761
|
+
Get the inverse of the quaternion.
|
|
762
|
+
|
|
763
|
+
Returns:
|
|
764
|
+
Quaternion: The inverse quaternion.
|
|
765
|
+
|
|
766
|
+
Example:
|
|
767
|
+
>>> q = Quaternion.unit()
|
|
768
|
+
>>> inverse = q.to_inverse()
|
|
769
|
+
"""
|
|
268
770
|
def to_normalized(self) -> Quaternion:
|
|
269
|
-
|
|
771
|
+
"""
|
|
772
|
+
Get a normalized copy of the quaternion.
|
|
773
|
+
|
|
774
|
+
Returns:
|
|
775
|
+
Quaternion: The normalized quaternion.
|
|
776
|
+
|
|
777
|
+
Example:
|
|
778
|
+
>>> q = Quaternion(1.0, 1.0, 1.0, 1.0, Quaternion.Format.XYZS)
|
|
779
|
+
>>> normalized = q.to_normalized()
|
|
780
|
+
"""
|
|
270
781
|
@typing.overload
|
|
271
782
|
def to_string(self) -> ostk.core.type.String:
|
|
272
|
-
|
|
783
|
+
"""
|
|
784
|
+
Convert the quaternion to string representation.
|
|
785
|
+
|
|
786
|
+
Returns:
|
|
787
|
+
str: String representation of the quaternion.
|
|
788
|
+
|
|
789
|
+
Example:
|
|
790
|
+
>>> q = Quaternion.unit()
|
|
791
|
+
>>> q.to_string()
|
|
792
|
+
"""
|
|
273
793
|
@typing.overload
|
|
274
|
-
def to_string(self,
|
|
275
|
-
|
|
794
|
+
def to_string(self, format: typing.Any) -> ostk.core.type.String:
|
|
795
|
+
"""
|
|
796
|
+
Convert the quaternion to string representation with specified format.
|
|
797
|
+
|
|
798
|
+
Args:
|
|
799
|
+
format (Quaternion.Format): The format for string representation.
|
|
800
|
+
|
|
801
|
+
Returns:
|
|
802
|
+
str: String representation of the quaternion.
|
|
803
|
+
|
|
804
|
+
Example:
|
|
805
|
+
>>> q = Quaternion.unit()
|
|
806
|
+
>>> q.to_string(Quaternion.Format.SXYZ)
|
|
807
|
+
"""
|
|
276
808
|
def to_vector(self, format: typing.Any) -> numpy.ndarray[numpy.float64[4, 1]]:
|
|
277
|
-
|
|
809
|
+
"""
|
|
810
|
+
Convert the quaternion to a 4D vector.
|
|
811
|
+
|
|
812
|
+
Args:
|
|
813
|
+
format (Quaternion.Format): The format for the vector components.
|
|
814
|
+
|
|
815
|
+
Returns:
|
|
816
|
+
Vector4d: The quaternion as a 4D vector.
|
|
817
|
+
|
|
818
|
+
Example:
|
|
819
|
+
>>> q = Quaternion.unit()
|
|
820
|
+
>>> vector = q.to_vector(Quaternion.Format.XYZS)
|
|
821
|
+
"""
|
|
278
822
|
def x(self) -> ostk.core.type.Real:
|
|
279
|
-
|
|
823
|
+
"""
|
|
824
|
+
Get the x-coordinate of the quaternion.
|
|
825
|
+
|
|
826
|
+
Returns:
|
|
827
|
+
float: The x-coordinate.
|
|
828
|
+
"""
|
|
280
829
|
def y(self) -> ostk.core.type.Real:
|
|
281
|
-
|
|
830
|
+
"""
|
|
831
|
+
Get the y-coordinate of the quaternion.
|
|
832
|
+
|
|
833
|
+
Returns:
|
|
834
|
+
float: The y-coordinate.
|
|
835
|
+
"""
|
|
282
836
|
def z(self) -> ostk.core.type.Real:
|
|
283
|
-
|
|
837
|
+
"""
|
|
838
|
+
Get the z-coordinate of the quaternion.
|
|
839
|
+
|
|
840
|
+
Returns:
|
|
841
|
+
float: The z-coordinate.
|
|
842
|
+
"""
|
|
284
843
|
class RotationMatrix:
|
|
285
844
|
__hash__: typing.ClassVar[None] = None
|
|
286
845
|
@staticmethod
|
|
287
846
|
def columns(first_column: numpy.ndarray[numpy.float64[3, 1]], second_column: numpy.ndarray[numpy.float64[3, 1]], third_column: numpy.ndarray[numpy.float64[3, 1]]) -> RotationMatrix:
|
|
288
|
-
|
|
847
|
+
"""
|
|
848
|
+
Create a rotation matrix from column vectors.
|
|
849
|
+
|
|
850
|
+
Args:
|
|
851
|
+
first_column (Vector3d): The first column of the rotation matrix.
|
|
852
|
+
second_column (Vector3d): The second column of the rotation matrix.
|
|
853
|
+
third_column (Vector3d): The third column of the rotation matrix.
|
|
854
|
+
|
|
855
|
+
Returns:
|
|
856
|
+
RotationMatrix: A rotation matrix from column vectors.
|
|
857
|
+
|
|
858
|
+
Example:
|
|
859
|
+
>>> rot_matrix = RotationMatrix.columns(Vector3d(1.0, 0.0, 0.0), Vector3d(0.0, 1.0, 0.0), Vector3d(0.0, 0.0, 1.0))
|
|
860
|
+
"""
|
|
289
861
|
@staticmethod
|
|
290
862
|
def euler_angle(euler_angle: typing.Any) -> RotationMatrix:
|
|
291
|
-
|
|
863
|
+
"""
|
|
864
|
+
Create a rotation matrix from Euler angles.
|
|
865
|
+
|
|
866
|
+
Args:
|
|
867
|
+
euler_angle (EulerAngle): The Euler angles to convert.
|
|
868
|
+
|
|
869
|
+
Returns:
|
|
870
|
+
RotationMatrix: The equivalent rotation matrix.
|
|
871
|
+
|
|
872
|
+
Example:
|
|
873
|
+
>>> euler = EulerAngle.unit()
|
|
874
|
+
>>> rot_matrix = RotationMatrix.euler_angle(euler)
|
|
875
|
+
"""
|
|
292
876
|
@staticmethod
|
|
293
877
|
def quaternion(quaternion: Quaternion) -> RotationMatrix:
|
|
294
|
-
|
|
878
|
+
"""
|
|
879
|
+
Create a rotation matrix from a quaternion.
|
|
880
|
+
|
|
881
|
+
Args:
|
|
882
|
+
quaternion (Quaternion): The quaternion to convert.
|
|
883
|
+
|
|
884
|
+
Returns:
|
|
885
|
+
RotationMatrix: The equivalent rotation matrix.
|
|
886
|
+
|
|
887
|
+
Example:
|
|
888
|
+
>>> quat = Quaternion.unit()
|
|
889
|
+
>>> rot_matrix = RotationMatrix.quaternion(quat)
|
|
890
|
+
"""
|
|
295
891
|
@staticmethod
|
|
296
892
|
def rotation_vector(rotation_vector: RotationVector) -> RotationMatrix:
|
|
297
|
-
|
|
893
|
+
"""
|
|
894
|
+
Create a rotation matrix from a rotation vector.
|
|
895
|
+
|
|
896
|
+
Args:
|
|
897
|
+
rotation_vector (RotationVector): The rotation vector to convert.
|
|
898
|
+
|
|
899
|
+
Returns:
|
|
900
|
+
RotationMatrix: The equivalent rotation matrix.
|
|
901
|
+
|
|
902
|
+
Example:
|
|
903
|
+
>>> rot_vector = RotationVector.unit()
|
|
904
|
+
>>> rot_matrix = RotationMatrix.rotation_vector(rot_vector)
|
|
905
|
+
"""
|
|
298
906
|
@staticmethod
|
|
299
907
|
def rows(first_row: numpy.ndarray[numpy.float64[3, 1]], second_row: numpy.ndarray[numpy.float64[3, 1]], third_row: numpy.ndarray[numpy.float64[3, 1]]) -> RotationMatrix:
|
|
300
|
-
|
|
908
|
+
"""
|
|
909
|
+
Create a rotation matrix from row vectors.
|
|
910
|
+
|
|
911
|
+
Args:
|
|
912
|
+
first_row (Vector3d): The first row of the rotation matrix.
|
|
913
|
+
second_row (Vector3d): The second row of the rotation matrix.
|
|
914
|
+
third_row (Vector3d): The third row of the rotation matrix.
|
|
915
|
+
|
|
916
|
+
Returns:
|
|
917
|
+
RotationMatrix: A rotation matrix from row vectors.
|
|
918
|
+
|
|
919
|
+
Example:
|
|
920
|
+
>>> rot_matrix = RotationMatrix.rows(Vector3d(1.0, 0.0, 0.0), Vector3d(0.0, 1.0, 0.0), Vector3d(0.0, 0.0, 1.0))
|
|
921
|
+
"""
|
|
301
922
|
@staticmethod
|
|
302
923
|
def rx(rotation_angle: typing.Any) -> RotationMatrix:
|
|
303
|
-
|
|
924
|
+
"""
|
|
925
|
+
Create a rotation matrix for rotation around the X-axis.
|
|
926
|
+
|
|
927
|
+
Args:
|
|
928
|
+
rotation_angle (Angle): The angle of rotation around X-axis.
|
|
929
|
+
|
|
930
|
+
Returns:
|
|
931
|
+
RotationMatrix: A rotation matrix for X-axis rotation.
|
|
932
|
+
|
|
933
|
+
Example:
|
|
934
|
+
>>> rot_x = RotationMatrix.rx(Angle.degrees(90.0))
|
|
935
|
+
"""
|
|
304
936
|
@staticmethod
|
|
305
937
|
def ry(rotation_angle: typing.Any) -> RotationMatrix:
|
|
306
|
-
|
|
938
|
+
"""
|
|
939
|
+
Create a rotation matrix for rotation around the Y-axis.
|
|
940
|
+
|
|
941
|
+
Args:
|
|
942
|
+
rotation_angle (Angle): The angle of rotation around Y-axis.
|
|
943
|
+
|
|
944
|
+
Returns:
|
|
945
|
+
RotationMatrix: A rotation matrix for Y-axis rotation.
|
|
946
|
+
|
|
947
|
+
Example:
|
|
948
|
+
>>> rot_y = RotationMatrix.ry(Angle.degrees(90.0))
|
|
949
|
+
"""
|
|
307
950
|
@staticmethod
|
|
308
951
|
def rz(rotation_angle: typing.Any) -> RotationMatrix:
|
|
309
|
-
|
|
952
|
+
"""
|
|
953
|
+
Create a rotation matrix for rotation around the Z-axis.
|
|
954
|
+
|
|
955
|
+
Args:
|
|
956
|
+
rotation_angle (Angle): The angle of rotation around Z-axis.
|
|
957
|
+
|
|
958
|
+
Returns:
|
|
959
|
+
RotationMatrix: A rotation matrix for Z-axis rotation.
|
|
960
|
+
|
|
961
|
+
Example:
|
|
962
|
+
>>> rot_z = RotationMatrix.rz(Angle.degrees(90.0))
|
|
963
|
+
"""
|
|
310
964
|
@staticmethod
|
|
311
965
|
def undefined() -> RotationMatrix:
|
|
312
|
-
|
|
966
|
+
"""
|
|
967
|
+
Create an undefined rotation matrix.
|
|
968
|
+
|
|
969
|
+
Returns:
|
|
970
|
+
RotationMatrix: An undefined rotation matrix.
|
|
971
|
+
|
|
972
|
+
Example:
|
|
973
|
+
>>> undefined_matrix = RotationMatrix.undefined()
|
|
974
|
+
>>> undefined_matrix.is_defined() # False
|
|
975
|
+
"""
|
|
313
976
|
@staticmethod
|
|
314
977
|
def unit() -> RotationMatrix:
|
|
315
|
-
|
|
978
|
+
"""
|
|
979
|
+
Create a unit rotation matrix (identity matrix).
|
|
980
|
+
|
|
981
|
+
Returns:
|
|
982
|
+
RotationMatrix: The 3x3 identity rotation matrix.
|
|
983
|
+
|
|
984
|
+
Example:
|
|
985
|
+
>>> unit_matrix = RotationMatrix.unit()
|
|
986
|
+
>>> matrix = unit_matrix.get_matrix() # 3x3 identity matrix
|
|
987
|
+
"""
|
|
316
988
|
def __eq__(self, arg0: RotationMatrix) -> bool:
|
|
317
989
|
...
|
|
318
990
|
@typing.overload
|
|
319
991
|
def __init__(self, matrix: numpy.ndarray[numpy.float64[3, 3]]) -> None:
|
|
320
|
-
|
|
992
|
+
"""
|
|
993
|
+
Create a rotation matrix from a 3x3 matrix.
|
|
994
|
+
|
|
995
|
+
Args:
|
|
996
|
+
matrix (Matrix3d): A 3x3 matrix representing the rotation.
|
|
997
|
+
|
|
998
|
+
Example:
|
|
999
|
+
>>> matrix = Matrix3d.identity()
|
|
1000
|
+
>>> rotation_matrix = RotationMatrix(matrix)
|
|
1001
|
+
"""
|
|
321
1002
|
@typing.overload
|
|
322
1003
|
def __init__(self, first_coefficient: ostk.core.type.Real, second_coefficient: ostk.core.type.Real, third_coefficient: ostk.core.type.Real, fourth_coefficient: ostk.core.type.Real, fifth_coefficient: ostk.core.type.Real, sixth_coefficient: ostk.core.type.Real, seventh_coefficient: ostk.core.type.Real, eighth_coefficient: ostk.core.type.Real, ninth_coefficient: ostk.core.type.Real) -> None:
|
|
323
|
-
|
|
1004
|
+
"""
|
|
1005
|
+
Create a rotation matrix from nine coefficients (row-major order).
|
|
1006
|
+
|
|
1007
|
+
Args:
|
|
1008
|
+
first_coefficient (float): Matrix element (0,0).
|
|
1009
|
+
second_coefficient (float): Matrix element (0,1).
|
|
1010
|
+
third_coefficient (float): Matrix element (0,2).
|
|
1011
|
+
fourth_coefficient (float): Matrix element (1,0).
|
|
1012
|
+
fifth_coefficient (float): Matrix element (1,1).
|
|
1013
|
+
sixth_coefficient (float): Matrix element (1,2).
|
|
1014
|
+
seventh_coefficient (float): Matrix element (2,0).
|
|
1015
|
+
eighth_coefficient (float): Matrix element (2,1).
|
|
1016
|
+
ninth_coefficient (float): Matrix element (2,2).
|
|
1017
|
+
|
|
1018
|
+
Example:
|
|
1019
|
+
>>> rot_matrix = RotationMatrix(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)
|
|
1020
|
+
"""
|
|
324
1021
|
@typing.overload
|
|
325
1022
|
def __mul__(self, arg0: RotationMatrix) -> RotationMatrix:
|
|
326
1023
|
...
|
|
@@ -334,51 +1031,216 @@ class RotationMatrix:
|
|
|
334
1031
|
def __str__(self) -> str:
|
|
335
1032
|
...
|
|
336
1033
|
def get_column_at(self, index: int) -> numpy.ndarray[numpy.float64[3, 1]]:
|
|
337
|
-
|
|
1034
|
+
"""
|
|
1035
|
+
Get a column of the rotation matrix at specified index.
|
|
1036
|
+
|
|
1037
|
+
Args:
|
|
1038
|
+
index (int): The column index (0, 1, or 2).
|
|
1039
|
+
|
|
1040
|
+
Returns:
|
|
1041
|
+
Vector3d: The column vector at the specified index.
|
|
1042
|
+
|
|
1043
|
+
Example:
|
|
1044
|
+
>>> rot_matrix = RotationMatrix.unit()
|
|
1045
|
+
>>> first_column = rot_matrix.get_column_at(0) # [1, 0, 0]
|
|
1046
|
+
"""
|
|
338
1047
|
def get_matrix(self) -> numpy.ndarray[numpy.float64[3, 3]]:
|
|
339
|
-
|
|
1048
|
+
"""
|
|
1049
|
+
Get the underlying 3x3 matrix.
|
|
1050
|
+
|
|
1051
|
+
Returns:
|
|
1052
|
+
Matrix3d: The 3x3 rotation matrix.
|
|
1053
|
+
|
|
1054
|
+
Example:
|
|
1055
|
+
>>> rot_matrix = RotationMatrix.unit()
|
|
1056
|
+
>>> matrix = rot_matrix.get_matrix()
|
|
1057
|
+
"""
|
|
340
1058
|
def get_row_at(self, index: int) -> numpy.ndarray[numpy.float64[3, 1]]:
|
|
341
|
-
|
|
1059
|
+
"""
|
|
1060
|
+
Get a row of the rotation matrix at specified index.
|
|
1061
|
+
|
|
1062
|
+
Args:
|
|
1063
|
+
index (int): The row index (0, 1, or 2).
|
|
1064
|
+
|
|
1065
|
+
Returns:
|
|
1066
|
+
Vector3d: The row vector at the specified index.
|
|
1067
|
+
|
|
1068
|
+
Example:
|
|
1069
|
+
>>> rot_matrix = RotationMatrix.unit()
|
|
1070
|
+
>>> first_row = rot_matrix.get_row_at(0) # [1, 0, 0]
|
|
1071
|
+
"""
|
|
342
1072
|
def is_defined(self) -> bool:
|
|
343
|
-
|
|
1073
|
+
"""
|
|
1074
|
+
Check if the rotation matrix is defined.
|
|
1075
|
+
|
|
1076
|
+
Returns:
|
|
1077
|
+
bool: True if the rotation matrix is defined, False otherwise.
|
|
1078
|
+
|
|
1079
|
+
Example:
|
|
1080
|
+
>>> rot_matrix = RotationMatrix(Matrix3d.identity())
|
|
1081
|
+
>>> rot_matrix.is_defined() # True
|
|
1082
|
+
"""
|
|
344
1083
|
def to_transposed(self) -> RotationMatrix:
|
|
345
|
-
|
|
1084
|
+
"""
|
|
1085
|
+
Get the transpose of this rotation matrix.
|
|
1086
|
+
|
|
1087
|
+
Returns:
|
|
1088
|
+
RotationMatrix: The transposed rotation matrix.
|
|
1089
|
+
|
|
1090
|
+
Example:
|
|
1091
|
+
>>> rot_matrix = RotationMatrix.rx(Angle.degrees(90.0))
|
|
1092
|
+
>>> transposed = rot_matrix.to_transposed()
|
|
1093
|
+
"""
|
|
346
1094
|
def transpose(self) -> None:
|
|
347
|
-
|
|
1095
|
+
"""
|
|
1096
|
+
Transpose the rotation matrix in place.
|
|
1097
|
+
|
|
1098
|
+
Example:
|
|
1099
|
+
>>> rot_matrix = RotationMatrix.rx(Angle.degrees(90.0))
|
|
1100
|
+
>>> rot_matrix.transpose()
|
|
1101
|
+
"""
|
|
348
1102
|
class RotationVector:
|
|
349
1103
|
__hash__: typing.ClassVar[None] = None
|
|
350
1104
|
@staticmethod
|
|
351
1105
|
def euler_angle(euler_angle: typing.Any) -> RotationVector:
|
|
352
|
-
|
|
1106
|
+
"""
|
|
1107
|
+
Create a rotation vector from Euler angles.
|
|
1108
|
+
|
|
1109
|
+
Args:
|
|
1110
|
+
euler_angle (EulerAngle): The Euler angles to convert.
|
|
1111
|
+
|
|
1112
|
+
Returns:
|
|
1113
|
+
RotationVector: The equivalent rotation vector.
|
|
1114
|
+
|
|
1115
|
+
Example:
|
|
1116
|
+
>>> ea = EulerAngle.zyx(Angle.degrees(30), Angle.degrees(45), Angle.degrees(60))
|
|
1117
|
+
>>> rot_vector = RotationVector.euler_angle(ea)
|
|
1118
|
+
"""
|
|
353
1119
|
@staticmethod
|
|
354
1120
|
def quaternion(quaternion: Quaternion) -> RotationVector:
|
|
355
|
-
|
|
1121
|
+
"""
|
|
1122
|
+
Create a rotation vector from a quaternion.
|
|
1123
|
+
|
|
1124
|
+
Args:
|
|
1125
|
+
quaternion (Quaternion): The quaternion to convert.
|
|
1126
|
+
|
|
1127
|
+
Returns:
|
|
1128
|
+
RotationVector: The equivalent rotation vector.
|
|
1129
|
+
|
|
1130
|
+
Example:
|
|
1131
|
+
>>> q = Quaternion.unit()
|
|
1132
|
+
>>> rot_vector = RotationVector.quaternion(q)
|
|
1133
|
+
"""
|
|
356
1134
|
@staticmethod
|
|
357
1135
|
def rotation_matrix(rotation_matrix: typing.Any) -> RotationVector:
|
|
358
|
-
|
|
1136
|
+
"""
|
|
1137
|
+
Create a rotation vector from a rotation matrix.
|
|
1138
|
+
|
|
1139
|
+
Args:
|
|
1140
|
+
rotation_matrix (RotationMatrix): The rotation matrix to convert.
|
|
1141
|
+
|
|
1142
|
+
Returns:
|
|
1143
|
+
RotationVector: The equivalent rotation vector.
|
|
1144
|
+
|
|
1145
|
+
Example:
|
|
1146
|
+
>>> rm = RotationMatrix.identity()
|
|
1147
|
+
>>> rot_vector = RotationVector.rotation_matrix(rm)
|
|
1148
|
+
"""
|
|
359
1149
|
@staticmethod
|
|
360
1150
|
def undefined() -> RotationVector:
|
|
361
|
-
|
|
1151
|
+
"""
|
|
1152
|
+
Create an undefined rotation vector.
|
|
1153
|
+
|
|
1154
|
+
Returns:
|
|
1155
|
+
RotationVector: An undefined rotation vector.
|
|
1156
|
+
|
|
1157
|
+
Example:
|
|
1158
|
+
>>> undefined_vector = RotationVector.undefined()
|
|
1159
|
+
>>> undefined_vector.is_defined() # False
|
|
1160
|
+
"""
|
|
362
1161
|
@staticmethod
|
|
363
1162
|
def unit() -> RotationVector:
|
|
364
|
-
|
|
1163
|
+
"""
|
|
1164
|
+
Create a unit rotation vector (no rotation).
|
|
1165
|
+
|
|
1166
|
+
Returns:
|
|
1167
|
+
RotationVector: A rotation vector representing no rotation.
|
|
1168
|
+
|
|
1169
|
+
Example:
|
|
1170
|
+
>>> unit_vector = RotationVector.unit()
|
|
1171
|
+
>>> angle = unit_vector.get_angle() # 0 degrees
|
|
1172
|
+
"""
|
|
365
1173
|
@staticmethod
|
|
366
1174
|
def x(angle: typing.Any) -> RotationVector:
|
|
367
|
-
|
|
1175
|
+
"""
|
|
1176
|
+
Create a rotation vector around the x-axis.
|
|
1177
|
+
|
|
1178
|
+
Args:
|
|
1179
|
+
angle (Angle): The rotation angle around the x-axis.
|
|
1180
|
+
|
|
1181
|
+
Returns:
|
|
1182
|
+
RotationVector: A rotation vector around the x-axis.
|
|
1183
|
+
|
|
1184
|
+
Example:
|
|
1185
|
+
>>> rot_vector = RotationVector.x(Angle.degrees(90.0))
|
|
1186
|
+
"""
|
|
368
1187
|
@staticmethod
|
|
369
1188
|
def y(angle: typing.Any) -> RotationVector:
|
|
370
|
-
|
|
1189
|
+
"""
|
|
1190
|
+
Create a rotation vector around the y-axis.
|
|
1191
|
+
|
|
1192
|
+
Args:
|
|
1193
|
+
angle (Angle): The rotation angle around the y-axis.
|
|
1194
|
+
|
|
1195
|
+
Returns:
|
|
1196
|
+
RotationVector: A rotation vector around the y-axis.
|
|
1197
|
+
|
|
1198
|
+
Example:
|
|
1199
|
+
>>> rot_vector = RotationVector.y(Angle.degrees(90.0))
|
|
1200
|
+
"""
|
|
371
1201
|
@staticmethod
|
|
372
1202
|
def z(angle: typing.Any) -> RotationVector:
|
|
373
|
-
|
|
1203
|
+
"""
|
|
1204
|
+
Create a rotation vector around the z-axis.
|
|
1205
|
+
|
|
1206
|
+
Args:
|
|
1207
|
+
angle (Angle): The rotation angle around the z-axis.
|
|
1208
|
+
|
|
1209
|
+
Returns:
|
|
1210
|
+
RotationVector: A rotation vector around the z-axis.
|
|
1211
|
+
|
|
1212
|
+
Example:
|
|
1213
|
+
>>> rot_vector = RotationVector.z(Angle.degrees(90.0))
|
|
1214
|
+
"""
|
|
374
1215
|
def __eq__(self, arg0: RotationVector) -> bool:
|
|
375
1216
|
...
|
|
376
1217
|
@typing.overload
|
|
377
1218
|
def __init__(self, axis: numpy.ndarray[numpy.float64[3, 1]], angle: typing.Any) -> None:
|
|
378
|
-
|
|
1219
|
+
"""
|
|
1220
|
+
Create a rotation vector from axis and angle.
|
|
1221
|
+
|
|
1222
|
+
Args:
|
|
1223
|
+
axis (np.array): The rotation axis (will be normalized).
|
|
1224
|
+
angle (Angle): The rotation angle around the axis.
|
|
1225
|
+
|
|
1226
|
+
Example:
|
|
1227
|
+
>>> axis = np.array([0.0, 0.0, 1.0])
|
|
1228
|
+
>>> angle = Angle.degrees(90.0)
|
|
1229
|
+
>>> rot_vector = RotationVector(axis, angle)
|
|
1230
|
+
"""
|
|
379
1231
|
@typing.overload
|
|
380
1232
|
def __init__(self, vector: numpy.ndarray[numpy.float64[3, 1]], angle_unit: typing.Any) -> None:
|
|
381
|
-
|
|
1233
|
+
"""
|
|
1234
|
+
Create a rotation vector from a vector representation.
|
|
1235
|
+
|
|
1236
|
+
Args:
|
|
1237
|
+
vector (np.array): The rotation vector (magnitude represents angle).
|
|
1238
|
+
angle_unit (Angle.Unit): The unit of the angle in the vector magnitude.
|
|
1239
|
+
|
|
1240
|
+
Example:
|
|
1241
|
+
>>> vector = np.array([0.0, 0.0, 1.5708]) # π/2 in z-axis
|
|
1242
|
+
>>> rot_vector = RotationVector(vector, Angle.Unit.Radian)
|
|
1243
|
+
"""
|
|
382
1244
|
def __ne__(self, arg0: RotationVector) -> bool:
|
|
383
1245
|
...
|
|
384
1246
|
def __repr__(self) -> str:
|
|
@@ -386,18 +1248,72 @@ class RotationVector:
|
|
|
386
1248
|
def __str__(self) -> str:
|
|
387
1249
|
...
|
|
388
1250
|
def get_angle(self) -> ...:
|
|
389
|
-
|
|
1251
|
+
"""
|
|
1252
|
+
Get the rotation angle.
|
|
1253
|
+
|
|
1254
|
+
Returns:
|
|
1255
|
+
Angle: The rotation angle around the axis.
|
|
1256
|
+
|
|
1257
|
+
Example:
|
|
1258
|
+
>>> rot_vector = RotationVector(axis, Angle.degrees(90.0))
|
|
1259
|
+
>>> angle = rot_vector.get_angle() # 90 degrees
|
|
1260
|
+
"""
|
|
390
1261
|
def get_axis(self) -> numpy.ndarray[numpy.float64[3, 1]]:
|
|
391
|
-
|
|
1262
|
+
"""
|
|
1263
|
+
Get the rotation axis vector.
|
|
1264
|
+
|
|
1265
|
+
Returns:
|
|
1266
|
+
Vector3d: The normalized rotation axis.
|
|
1267
|
+
|
|
1268
|
+
Example:
|
|
1269
|
+
>>> rot_vector = RotationVector(np.array([1.0, 0.0, 0.0]), angle)
|
|
1270
|
+
>>> axis = rot_vector.get_axis() # [1.0, 0.0, 0.0]
|
|
1271
|
+
"""
|
|
392
1272
|
def is_defined(self) -> bool:
|
|
393
|
-
|
|
1273
|
+
"""
|
|
1274
|
+
Check if the rotation vector is defined.
|
|
1275
|
+
|
|
1276
|
+
Returns:
|
|
1277
|
+
bool: True if the rotation vector is defined, False otherwise.
|
|
1278
|
+
|
|
1279
|
+
Example:
|
|
1280
|
+
>>> rot_vector = RotationVector(axis, angle)
|
|
1281
|
+
>>> rot_vector.is_defined() # True
|
|
1282
|
+
"""
|
|
394
1283
|
def rectify(self) -> None:
|
|
395
|
-
|
|
1284
|
+
"""
|
|
1285
|
+
Rectify the rotation vector in-place (ensure angle is in [0, π]).
|
|
1286
|
+
|
|
1287
|
+
Example:
|
|
1288
|
+
>>> rot_vector = RotationVector(axis, Angle.degrees(270.0))
|
|
1289
|
+
>>> rot_vector.rectify() # Converts to equivalent rotation with angle ≤ π
|
|
1290
|
+
"""
|
|
396
1291
|
@typing.overload
|
|
397
1292
|
def to_string(self) -> ostk.core.type.String:
|
|
398
|
-
|
|
1293
|
+
"""
|
|
1294
|
+
Convert the rotation vector to string representation.
|
|
1295
|
+
|
|
1296
|
+
Returns:
|
|
1297
|
+
str: String representation of the rotation vector.
|
|
1298
|
+
|
|
1299
|
+
Example:
|
|
1300
|
+
>>> rot_vector = RotationVector.unit()
|
|
1301
|
+
>>> rot_vector.to_string()
|
|
1302
|
+
"""
|
|
399
1303
|
@typing.overload
|
|
400
|
-
def to_string(self,
|
|
401
|
-
|
|
1304
|
+
def to_string(self, precision: ostk.core.type.Integer) -> ostk.core.type.String:
|
|
1305
|
+
"""
|
|
1306
|
+
Convert the rotation vector to string representation with specified precision.
|
|
1307
|
+
|
|
1308
|
+
Args:
|
|
1309
|
+
precision (int): The precision for floating point numbers.
|
|
1310
|
+
|
|
1311
|
+
Returns:
|
|
1312
|
+
str: String representation of the rotation vector.
|
|
1313
|
+
|
|
1314
|
+
Example:
|
|
1315
|
+
>>> rot_vector = RotationVector.unit()
|
|
1316
|
+
>>> rot_vector.to_string(3)
|
|
1317
|
+
"""
|
|
402
1318
|
def set_quaternion_array(arg0: list[Quaternion]) -> None:
|
|
403
1319
|
...
|