or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

extensions.mdindex.mdmath-functions.mdmatrices.mdquaternions.mdrandom-noise.mdtransformations.mdutilities.mdvectors.md

quaternions.mddocs/

0

# Quaternion Operations

1

2

Efficient 3D rotation representation using quaternions. Quaternions provide smooth interpolation, avoid gimbal lock, and offer compact storage for rotations in 3D graphics and physics applications.

3

4

## Capabilities

5

6

### Quaternion Types

7

8

PyGLM provides quaternion types in different precisions for various performance and accuracy requirements.

9

10

```python { .api }

11

class quat:

12

"""

13

Single-precision quaternion for 3D rotations.

14

Components: w (scalar), x, y, z (vector)

15

"""

16

w: float # Scalar component

17

x: float # X vector component

18

y: float # Y vector component

19

z: float # Z vector component

20

21

def __init__(self): ... # Identity quaternion (0, 0, 0, 1)

22

def __init__(self, w: float, x: float, y: float, z: float): ... # From components

23

def __init__(self, v: vec3): ... # From Euler angles

24

def __init__(self, m: mat3): ... # From rotation matrix

25

def __init__(self, m: mat4): ... # From transformation matrix

26

27

class dquat:

28

"""

29

Double-precision quaternion for high-accuracy rotations.

30

Components: w (scalar), x, y, z (vector)

31

"""

32

w: float # Scalar component (double precision)

33

x: float # X vector component (double precision)

34

y: float # Y vector component (double precision)

35

z: float # Z vector component (double precision)

36

37

def __init__(self): ... # Identity quaternion

38

def __init__(self, w: float, x: float, y: float, z: float): ...

39

def __init__(self, v: vec3): ... # From Euler angles

40

def __init__(self, m: mat3): ... # From rotation matrix

41

def __init__(self, m: mat4): ... # From transformation matrix

42

```

43

44

### Quaternion Construction

45

46

Functions for creating quaternions from various rotation representations.

47

48

```python { .api }

49

def angleAxis(angle, axis):

50

"""

51

Create a quaternion from an angle and rotation axis.

52

53

Args:

54

angle: Rotation angle in radians

55

axis: Rotation axis vector (vec3, should be normalized)

56

57

Returns:

58

Quaternion representing the rotation

59

60

Example:

61

q = glm.angleAxis(glm.radians(45), glm.vec3(0, 1, 0)) # 45° around Y-axis

62

"""

63

64

def quatLookAt(direction, up):

65

"""

66

Create a quaternion that rotates to look in a specific direction.

67

68

Args:

69

direction: Direction to look toward (vec3, will be normalized)

70

up: Up vector (vec3, will be normalized)

71

72

Returns:

73

Quaternion representing the look-at rotation

74

"""

75

76

def euler(angles):

77

"""

78

Create a quaternion from Euler angles.

79

80

Args:

81

angles: Euler angles in radians (vec3: pitch, yaw, roll)

82

83

Returns:

84

Quaternion representing the combined rotation

85

86

Example:

87

q = glm.euler(glm.vec3(glm.radians(15), glm.radians(30), glm.radians(45)))

88

"""

89

```

90

91

### Quaternion Operations

92

93

Core quaternion mathematics including arithmetic, normalization, and conjugation.

94

95

```python { .api }

96

def normalize(q):

97

"""

98

Normalize a quaternion to unit length.

99

100

Args:

101

q: Quaternion to normalize

102

103

Returns:

104

Normalized quaternion (unit quaternion)

105

106

Note:

107

Unit quaternions represent pure rotations

108

"""

109

110

def conjugate(q):

111

"""

112

Calculate the conjugate of a quaternion.

113

114

Args:

115

q: Input quaternion

116

117

Returns:

118

Conjugate quaternion (negated vector part)

119

120

Note:

121

For unit quaternions, conjugate equals inverse

122

"""

123

124

def inverse(q):

125

"""

126

Calculate the inverse of a quaternion.

127

128

Args:

129

q: Input quaternion

130

131

Returns:

132

Inverse quaternion

133

"""

134

135

def length(q):

136

"""

137

Calculate the length (magnitude) of a quaternion.

138

139

Args:

140

q: Input quaternion

141

142

Returns:

143

Scalar length of the quaternion

144

"""

145

146

def dot(q1, q2):

147

"""

148

Calculate the dot product of two quaternions.

149

150

Args:

151

q1: First quaternion

152

q2: Second quaternion

153

154

Returns:

155

Scalar dot product

156

"""

157

```

158

159

### Quaternion Interpolation

160

161

Smooth interpolation functions for animation and smooth transitions between rotations.

162

163

```python { .api }

164

def slerp(x, y, a):

165

"""

166

Spherical linear interpolation between two quaternions.

167

168

Args:

169

x: Start quaternion

170

y: End quaternion

171

a: Interpolation factor (0.0 = x, 1.0 = y)

172

173

Returns:

174

Interpolated quaternion with constant angular velocity

175

176

Note:

177

SLERP provides the shortest rotation path between quaternions

178

"""

179

180

def lerp(x, y, a):

181

"""

182

Linear interpolation between two quaternions.

183

184

Args:

185

x: Start quaternion

186

y: End quaternion

187

a: Interpolation factor (0.0 = x, 1.0 = y)

188

189

Returns:

190

Linearly interpolated quaternion (requires normalization)

191

192

Note:

193

Faster than SLERP but doesn't maintain constant angular velocity

194

"""

195

196

def mix(x, y, a):

197

"""

198

Alias for lerp - linear interpolation between quaternions.

199

200

Args:

201

x: Start quaternion

202

y: End quaternion

203

a: Interpolation factor

204

205

Returns:

206

Linearly interpolated quaternion

207

"""

208

```

209

210

### Matrix Conversion

211

212

Functions for converting between quaternions and rotation matrices.

213

214

```python { .api }

215

def mat3_cast(q):

216

"""

217

Convert a quaternion to a 3×3 rotation matrix.

218

219

Args:

220

q: Quaternion to convert

221

222

Returns:

223

3×3 rotation matrix equivalent to the quaternion

224

225

Example:

226

rotation_matrix = glm.mat3_cast(quaternion)

227

"""

228

229

def mat4_cast(q):

230

"""

231

Convert a quaternion to a 4×4 transformation matrix.

232

233

Args:

234

q: Quaternion to convert

235

236

Returns:

237

4×4 transformation matrix with rotation and identity translation

238

239

Example:

240

transform_matrix = glm.mat4_cast(quaternion)

241

"""

242

243

def quat_cast(m):

244

"""

245

Convert a rotation matrix to a quaternion.

246

247

Args:

248

m: 3×3 or 4×4 rotation matrix

249

250

Returns:

251

Quaternion equivalent to the matrix rotation

252

253

Example:

254

quaternion = glm.quat_cast(rotation_matrix)

255

"""

256

```

257

258

### Euler Angle Conversion

259

260

Functions for converting between quaternions and Euler angle representations.

261

262

```python { .api }

263

def eulerAngles(q):

264

"""

265

Extract Euler angles from a quaternion.

266

267

Args:

268

q: Input quaternion

269

270

Returns:

271

vec3 containing Euler angles in radians (pitch, yaw, roll)

272

273

Example:

274

angles = glm.eulerAngles(quaternion)

275

pitch = angles.x

276

yaw = angles.y

277

roll = angles.z

278

"""

279

280

def pitch(q):

281

"""

282

Extract the pitch angle from a quaternion.

283

284

Args:

285

q: Input quaternion

286

287

Returns:

288

Pitch angle in radians (rotation around X-axis)

289

"""

290

291

def yaw(q):

292

"""

293

Extract the yaw angle from a quaternion.

294

295

Args:

296

q: Input quaternion

297

298

Returns:

299

Yaw angle in radians (rotation around Y-axis)

300

"""

301

302

def roll(q):

303

"""

304

Extract the roll angle from a quaternion.

305

306

Args:

307

q: Input quaternion

308

309

Returns:

310

Roll angle in radians (rotation around Z-axis)

311

"""

312

313

def angle(q):

314

"""

315

Extract the rotation angle from a quaternion.

316

317

Args:

318

q: Input quaternion

319

320

Returns:

321

Rotation angle in radians

322

"""

323

324

def axis(q):

325

"""

326

Extract the rotation axis from a quaternion.

327

328

Args:

329

q: Input quaternion

330

331

Returns:

332

vec3 representing the normalized rotation axis

333

"""

334

```

335

336

### Quaternion Arithmetic

337

338

All quaternion types support standard arithmetic operations through operator overloading:

339

340

- **Addition**: `q1 + q2` - Component-wise addition

341

- **Subtraction**: `q1 - q2` - Component-wise subtraction

342

- **Multiplication**: `q1 * q2` - Quaternion multiplication (composition of rotations)

343

- **Scalar Multiplication**: `q * scalar` - Scale quaternion components

344

- **Negation**: `-q` - Component-wise negation

345

- **Equality**: `q1 == q2`, `q1 != q2` - Component-wise equality

346

347

### Usage Examples

348

349

```python

350

from pyglm import glm

351

import math

352

353

# === Basic Quaternion Creation ===

354

355

# Identity quaternion (no rotation)

356

identity_quat = glm.quat()

357

358

# From explicit components (w, x, y, z)

359

explicit_quat = glm.quat(0.707, 0.0, 0.707, 0.0) # 90° around Y-axis

360

361

# From angle and axis

362

angle = glm.radians(45)

363

axis = glm.vec3(0, 1, 0) # Y-axis

364

angle_axis_quat = glm.angleAxis(angle, axis)

365

366

# From Euler angles (pitch, yaw, roll)

367

euler_angles = glm.vec3(glm.radians(15), glm.radians(30), glm.radians(45))

368

euler_quat = glm.euler(euler_angles)

369

370

# === Quaternion Operations ===

371

372

# Normalize quaternion (essential for rotations)

373

normalized_quat = glm.normalize(angle_axis_quat)

374

375

# Quaternion multiplication (combines rotations)

376

q1 = glm.angleAxis(glm.radians(30), glm.vec3(1, 0, 0)) # 30° around X

377

q2 = glm.angleAxis(glm.radians(45), glm.vec3(0, 1, 0)) # 45° around Y

378

combined_rotation = q2 * q1 # Apply q1 first, then q2

379

380

# Conjugate (inverse for unit quaternions)

381

inverse_rotation = glm.conjugate(normalized_quat)

382

383

# === Quaternion Interpolation for Animation ===

384

385

# SLERP for smooth rotation animation

386

start_quat = glm.angleAxis(glm.radians(0), glm.vec3(0, 1, 0))

387

end_quat = glm.angleAxis(glm.radians(90), glm.vec3(0, 1, 0))

388

389

# Animate from 0° to 90° over time

390

animation_time = 0.5 # 50% through animation

391

interpolated_quat = glm.slerp(start_quat, end_quat, animation_time)

392

393

# === Matrix Conversion ===

394

395

# Convert quaternion to rotation matrix

396

rotation_quat = glm.angleAxis(glm.radians(45), glm.vec3(0, 0, 1))

397

rotation_matrix_3x3 = glm.mat3_cast(rotation_quat)

398

rotation_matrix_4x4 = glm.mat4_cast(rotation_quat)

399

400

# Convert matrix back to quaternion

401

recovered_quat = glm.quat_cast(rotation_matrix_3x3)

402

403

# === Euler Angle Extraction ===

404

405

# Get Euler angles from quaternion

406

quaternion = glm.angleAxis(glm.radians(45), glm.vec3(1, 1, 0))

407

euler_angles = glm.eulerAngles(quaternion)

408

409

pitch_degrees = glm.degrees(euler_angles.x)

410

yaw_degrees = glm.degrees(euler_angles.y)

411

roll_degrees = glm.degrees(euler_angles.z)

412

413

# Extract individual components

414

pitch_rad = glm.pitch(quaternion)

415

yaw_rad = glm.yaw(quaternion)

416

roll_rad = glm.roll(quaternion)

417

418

# Extract angle and axis

419

rotation_angle = glm.angle(quaternion)

420

rotation_axis = glm.axis(quaternion)

421

422

# === Practical 3D Graphics Example ===

423

424

# Create a first-person camera rotation system

425

class FirstPersonCamera:

426

def __init__(self):

427

self.orientation = glm.quat() # Identity quaternion

428

self.sensitivity = 0.002 # Mouse sensitivity

429

430

def rotate(self, mouse_delta_x, mouse_delta_y):

431

# Yaw rotation (around world Y-axis)

432

yaw_rotation = glm.angleAxis(-mouse_delta_x * self.sensitivity, glm.vec3(0, 1, 0))

433

434

# Pitch rotation (around local X-axis)

435

pitch_rotation = glm.angleAxis(-mouse_delta_y * self.sensitivity, glm.vec3(1, 0, 0))

436

437

# Apply rotations: pitch first (local), then yaw (world)

438

self.orientation = yaw_rotation * self.orientation * pitch_rotation

439

self.orientation = glm.normalize(self.orientation)

440

441

def get_view_matrix(self, position):

442

# Convert quaternion to rotation matrix

443

rotation_matrix = glm.mat4_cast(glm.conjugate(self.orientation))

444

445

# Apply translation

446

view_matrix = glm.translate(rotation_matrix, -position)

447

return view_matrix

448

449

# Usage

450

camera = FirstPersonCamera()

451

camera.rotate(0.1, 0.05) # Simulate mouse movement

452

view_matrix = camera.get_view_matrix(glm.vec3(0, 2, 5))

453

454

# === Character Animation Example ===

455

456

# Smooth rotation between two orientations

457

old_facing = glm.angleAxis(glm.radians(0), glm.vec3(0, 1, 0)) # North

458

new_facing = glm.angleAxis(glm.radians(90), glm.vec3(0, 1, 0)) # East

459

460

# Smoothly rotate character over 2 seconds

461

animation_duration = 2.0

462

current_time = 0.75 # 0.75 seconds into animation

463

t = current_time / animation_duration

464

465

current_facing = glm.slerp(old_facing, new_facing, t)

466

character_transform = glm.mat4_cast(current_facing)

467

468

# === Look-At Quaternion ===

469

470

target_position = glm.vec3(10, 0, 0)

471

current_position = glm.vec3(0, 0, 0)

472

up_vector = glm.vec3(0, 1, 0)

473

474

look_direction = glm.normalize(target_position - current_position)

475

look_at_quat = glm.quatLookAt(look_direction, up_vector)

476

look_at_matrix = glm.mat4_cast(look_at_quat)

477

```

478

479

### Quaternion Best Practices

480

481

1. **Always normalize quaternions** used for rotations to ensure they remain unit quaternions

482

2. **Use SLERP for smooth animation** between rotations to maintain constant angular velocity

483

3. **Prefer quaternion multiplication** over Euler angle arithmetic to avoid gimbal lock

484

4. **Store orientations as quaternions** and convert to matrices only when needed for rendering

485

5. **Use conjugate instead of inverse** for unit quaternions (more efficient)

486

6. **Be consistent with rotation order** when converting between Euler angles and quaternions