cgse-coordinates 0.17.3__py3-none-any.whl → 0.18.0__py3-none-any.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.
@@ -0,0 +1,95 @@
1
+ """This module contains convenience methods to define and apply rotations."""
2
+
3
+ import transforms3d as t3
4
+ import numpy as np
5
+
6
+
7
+ class RotationMatrix:
8
+ ROTATION_CONFIG = "sxyz"
9
+
10
+ def __init__(self, angle_1: float, angle_2: float, angle_3: float, rotation_config=ROTATION_CONFIG, active=True):
11
+ """Initialisation of a rotation matrix.
12
+
13
+ The `angle_1`, `angle_2` and `angle_3` parameters provide the amplitude of rotation around the axes, according
14
+ to the order of rotations corresponding to the `rotation_config` parameter. The latter consist of four
15
+ characters:
16
+ - The first character: "r" for rotating system (intrinsic rotations) or "s" for static system (extrinsic
17
+ rotations).
18
+ - The next characters denote the order of the rotations.
19
+
20
+ Args:
21
+ angle_1 (float): Rotation angle for the first axis [radians]. To which angle this corresponds (x/y/z) is
22
+ specified by the `rotation_config` parameter.
23
+ angle_2 (float): Rotation angle for hte second axis [radians]. To which angle this corresponds (x/y/z) is
24
+ specified by the `rotation_config` parameter.
25
+ angle_3 (float): Rotation angle for the third axis [radians]. To which angle this corresponds (x/y/z) is
26
+ specified by the `rotation_config` parameter.
27
+ rotation_config (str): Order in which the rotation about the three axes are chained.
28
+ active (bool): Indicates if the rotation is active (object rotates IN a fixed coordinate system) or passive
29
+ (coordinate system rotates AROUND a fixed object). Even if two angles are zero, the match
30
+ between angle orders and rot_config is still critical.
31
+ """
32
+
33
+ rotation_matrix = t3.euler.euler2mat(angle_1, angle_2, angle_3, rotation_config)
34
+
35
+ if active:
36
+ # Active: The object rotates IN a fixed coordinate system
37
+ self.rotation_matrix = rotation_matrix
38
+ else:
39
+ # Passive: The coordinate system rotation AROUND a fixed object
40
+ self.rotation_matrix = rotation_matrix.T
41
+ self.active = active
42
+
43
+ rotation_config_array = np.array(list(rotation_config[1:]))
44
+ angles_array = np.array([angle_1, angle_2, angle_3])
45
+
46
+ self.angles_hash = {}
47
+ for axis in ["x", "y", "z"]:
48
+ self.angles_hash[axis] = angles_array[np.where(rotation_config_array == axis)[0][0]]
49
+
50
+ def get_rotation_matrix(self) -> np.ndarray:
51
+ """Returns the rotation matrix.
52
+
53
+ Returns:
54
+ Rotation matrix.
55
+ """
56
+
57
+ return self.rotation_matrix
58
+
59
+ def trace(self) -> float:
60
+ """Returns the trace of the rotation matrix.
61
+
62
+ Returns:
63
+ Trace of the rotation matrix.
64
+ """
65
+
66
+ return np.sum([self.rotation_matrix[i, i] for i in range(3)])
67
+
68
+ def get_angle(self, axis: str) -> float:
69
+ """Returns the angle for the given axis.
70
+
71
+ Args:
72
+ axis (str): Axis for which to return the angle ("x", "y", "z").
73
+
74
+ Returns:
75
+ Angle for the given axis.
76
+ """
77
+
78
+ return self.angles_hash[axis]
79
+
80
+ def apply(self, vectors: np.ndarray) -> np.ndarray:
81
+ """Applies the rotation matrix to the given vector.
82
+
83
+ The result depends on the rotation system:
84
+ - Active: The output consists of the coordinates of the input vectors after rotation.
85
+ - Passive: The output consists of the coordinates of the input vectors after transformation to the rotated
86
+ coordinate system.
87
+
88
+ Args:
89
+ vectors (np.ndarray): Array of shape [3,N] gathering a set of vectors along its columns.
90
+
91
+ Returns:
92
+ Array of shape [3,N] gathering a set of vectors along its columns.
93
+ """
94
+
95
+ return np.dot(self.rotation_matrix, vectors)