or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-operations.mdindex.mdrotation-conversions.mdtime-series.md

rotation-conversions.mddocs/

0

# Rotation Conversions

1

2

Convert between quaternions and various rotation representations including rotation matrices, axis-angle vectors, Euler angles, and spherical coordinates. These functions enable seamless integration with other rotation libraries and mathematical frameworks.

3

4

## Capabilities

5

6

### Rotation Matrix Conversions

7

8

Convert between quaternions and 3x3 rotation matrices.

9

10

```python { .api }

11

def as_rotation_matrix(q):

12

"""

13

Convert quaternions to 3x3 rotation matrices.

14

15

Args:

16

q (quaternion or quaternion array): Input quaternions (need not be normalized)

17

18

Returns:

19

ndarray: Rotation matrices with shape q.shape + (3, 3)

20

21

Raises:

22

ZeroDivisionError: If any input quaternion has zero norm

23

24

Notes:

25

For quaternion q and vector v, the rotated vector is:

26

rotated_v = rotation_matrix @ v.vec

27

where v.vec is the 3D vector part of quaternion v.

28

"""

29

30

def from_rotation_matrix(rot, nonorthogonal=True):

31

"""

32

Convert 3x3 rotation matrices to unit quaternions.

33

34

Args:

35

rot (array_like): Rotation matrices with shape (..., 3, 3)

36

nonorthogonal (bool): Use robust algorithm for non-orthogonal matrices (default: True)

37

38

Returns:

39

quaternion array: Unit quaternions with shape rot.shape[:-2]

40

41

Raises:

42

LinAlgError: If eigenvalue solutions do not converge (scipy algorithm)

43

44

Notes:

45

Uses Bar-Itzhack algorithm (scipy.linalg) when nonorthogonal=True for robustness.

46

Falls back to Markley algorithm when scipy unavailable or nonorthogonal=False.

47

"""

48

```

49

50

### Vector Rotation

51

52

Apply quaternion rotations to 3D vectors efficiently.

53

54

```python { .api }

55

def rotate_vectors(R, v, axis=-1):

56

"""

57

Rotate 3D vectors using quaternions.

58

59

Args:

60

R (quaternion array): Rotation quaternions

61

v (array_like): 3D vectors to rotate

62

axis (int): Axis of v containing vector components (must have length 3)

63

64

Returns:

65

ndarray: Rotated vectors with shape R.shape + v.shape

66

67

Notes:

68

More efficient than individual quaternion products when rotating

69

multiple vectors with the same quaternion. Uses matrix multiplication

70

internally for vectorized operations.

71

"""

72

```

73

74

### Axis-Angle Representations

75

76

Convert between quaternions and axis-angle (rotation vector) representations.

77

78

```python { .api }

79

def as_rotation_vector(q):

80

"""

81

Convert quaternions to axis-angle representation.

82

83

Args:

84

q (quaternion or quaternion array): Input quaternions (need not be normalized)

85

86

Returns:

87

ndarray: Rotation vectors with shape q.shape + (3,)

88

89

Notes:

90

Each vector represents rotation axis with magnitude equal to rotation

91

angle in radians. No error for zero-norm quaternions (produces NaN).

92

"""

93

94

def from_rotation_vector(rot):

95

"""

96

Convert axis-angle vectors to unit quaternions.

97

98

Args:

99

rot (array_like): Rotation vectors with shape (..., 3)

100

101

Returns:

102

quaternion array: Unit quaternions with shape rot.shape[:-1]

103

104

Notes:

105

Vector magnitude is rotation angle in radians, direction is rotation axis.

106

Uses quaternion exponential for conversion.

107

"""

108

```

109

110

### Euler Angle Conversions

111

112

Convert between quaternions and Euler angles with caveats about Euler angle limitations.

113

114

```python { .api }

115

def as_euler_angles(q):

116

"""

117

Convert quaternions to Euler angles (ZYZ convention).

118

119

Args:

120

q (quaternion or quaternion array): Input quaternions (need not be normalized)

121

122

Returns:

123

ndarray: Euler angles (alpha, beta, gamma) with shape q.shape + (3,)

124

125

Raises:

126

AllHell: Metaphorically, if you use Euler angles when you shouldn't

127

128

Notes:

129

Uses ZYZ convention: R = exp(alpha*z/2) * exp(beta*y/2) * exp(gamma*z/2)

130

Angles in radians. Euler angles have singularities and are generally

131

discouraged. See package documentation warnings about Euler angles.

132

"""

133

134

def from_euler_angles(alpha_beta_gamma, beta=None, gamma=None):

135

"""

136

Create quaternions from Euler angles (ZYZ convention).

137

138

Args:

139

alpha_beta_gamma (array_like): Euler angles array with last dim 3, or alpha values

140

beta (array_like, optional): Beta angles if alpha_beta_gamma contains only alpha

141

gamma (array_like, optional): Gamma angles if alpha_beta_gamma contains only alpha

142

143

Returns:

144

quaternion array: Quaternions from Euler angle inputs

145

146

Notes:

147

Uses ZYZ convention with angles in radians. Inputs must broadcast together.

148

Strongly consider using other rotation representations instead.

149

"""

150

```

151

152

### Spherical Coordinate Conversions

153

154

Convert between quaternions and spherical coordinates (theta, phi).

155

156

```python { .api }

157

def as_spherical_coords(q):

158

"""

159

Convert quaternions to spherical coordinates.

160

161

Args:

162

q (quaternion or quaternion array): Input quaternions (must be nonzero)

163

164

Returns:

165

ndarray: Spherical coordinates (theta, phi) with shape q.shape + (2,)

166

167

Notes:

168

Returns point on sphere where quaternion rotates z-axis. Loses some

169

information compared to full quaternion representation.

170

"""

171

172

def from_spherical_coords(theta_phi, phi=None):

173

"""

174

Create quaternions from spherical coordinates.

175

176

Args:

177

theta_phi (array_like): Coordinate array with last dim 2, or theta values

178

phi (array_like, optional): Phi coordinates if theta_phi contains only theta

179

180

Returns:

181

quaternion array: Quaternions rotating z-axis to specified coordinates

182

183

Notes:

184

Creates quaternion R = exp(phi*z/2) * exp(theta*y/2). Angles in radians.

185

Rotates z-axis to given spherical coordinates and x,y to local tangent basis.

186

"""

187

```

188

189

## Usage Examples

190

191

```python

192

import quaternion

193

import numpy as np

194

195

# Create sample quaternions

196

q = quaternion.quaternion(1, 0, 0, 0) # Identity

197

q_rot = quaternion.from_euler_angles(0, np.pi/4, 0) # 45° rotation around y

198

199

# Convert to rotation matrix

200

R = quaternion.as_rotation_matrix(q_rot)

201

print(f"Rotation matrix shape: {R.shape}") # (3, 3)

202

203

# Rotate vectors

204

vectors = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) # Identity matrix columns

205

rotated = quaternion.rotate_vectors(q_rot, vectors.T, axis=0)

206

print(f"Rotated vectors shape: {rotated.shape}")

207

208

# Convert to axis-angle representation

209

axis_angle = quaternion.as_rotation_vector(q_rot)

210

print(f"Axis-angle vector: {axis_angle}")

211

212

# Round-trip conversion

213

q_recovered = quaternion.from_rotation_vector(axis_angle)

214

print(f"Original close to recovered: {quaternion.allclose(q_rot, q_recovered)}")

215

216

# Convert to spherical coordinates

217

theta_phi = quaternion.as_spherical_coords(q_rot)

218

print(f"Spherical coords: theta={theta_phi[0]:.3f}, phi={theta_phi[1]:.3f}")

219

220

# Create from rotation matrix

221

R_input = np.array([[0, 1, 0], [-1, 0, 0], [0, 0, 1]]) # 90° rotation around z

222

q_from_matrix = quaternion.from_rotation_matrix(R_input)

223

print(f"Quaternion from matrix: {q_from_matrix}")

224

225

# Demonstrate quaternion-matrix equivalence

226

test_vector = np.array([1, 0, 0])

227

rotated_by_q = quaternion.as_vector_part(q_from_matrix * quaternion.from_vector_part(test_vector) * q_from_matrix.conjugate())

228

rotated_by_matrix = R_input @ test_vector

229

print(f"Quaternion rotation: {rotated_by_q}")

230

print(f"Matrix rotation: {rotated_by_matrix}")

231

print(f"Results match: {np.allclose(rotated_by_q, rotated_by_matrix)}")

232

```