or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

batch-operations.mdbatch-rotations.mdcamera.mdcoordinates.mdeditor.mdindex.mdplot-utils.mdrotations.mdtrajectories.mdtransform-manager.mdtransformations.mduncertainty.mdurdf.mdvisualization.md

rotations.mddocs/

0

# Rotations

1

2

Complete system for representing and converting between rotation formats in three dimensions (SO(3)). Supports matrices, quaternions, axis-angles, Euler angles, Modified Rodrigues Parameters, and geometric algebra rotors with comprehensive conversion functions and mathematical operations.

3

4

## Capabilities

5

6

### Rotation Matrix Operations

7

8

Operations for 3x3 rotation matrices including validation, normalization, and conversions.

9

10

```python { .api }

11

def check_matrix(R, tolerance=1e-6, strict_check=True):

12

"""Validate rotation matrix properties."""

13

14

def norm_matrix(R):

15

"""Normalize rotation matrix using SVD."""

16

17

def matrix_from_euler(e, i, j, k, extrinsic):

18

"""

19

Convert Euler angles to rotation matrix.

20

21

Parameters:

22

- e: array-like, shape (3,) - Euler angles in radians

23

- i: int from [0, 1, 2] - First rotation axis (0: x, 1: y, 2: z)

24

- j: int from [0, 1, 2] - Second rotation axis (0: x, 1: y, 2: z)

25

- k: int from [0, 1, 2] - Third rotation axis (0: x, 1: y, 2: z)

26

- extrinsic: bool - Extrinsic (True) or intrinsic (False) rotations

27

28

Returns:

29

- R: array, shape (3, 3) - Rotation matrix

30

"""

31

32

def matrix_from_quaternion(q):

33

"""Convert quaternion to rotation matrix."""

34

35

def matrix_from_axis_angle(a):

36

"""Convert axis-angle representation to rotation matrix."""

37

38

def matrix_from_compact_axis_angle(a):

39

"""Convert compact axis-angle to rotation matrix."""

40

41

def matrix_from_two_vectors(a, b):

42

"""Compute rotation matrix aligning vector a to vector b."""

43

44

def matrix_from_rotor(rotor):

45

"""Convert geometric algebra rotor to rotation matrix."""

46

```

47

48

### Quaternion Operations

49

50

Operations for unit quaternions including validation, composition, and interpolation.

51

52

```python { .api }

53

def check_quaternion(q, unit=True, tolerance=1e-6, strict_check=True):

54

"""Validate quaternion properties."""

55

56

def quaternion_from_matrix(R):

57

"""Convert rotation matrix to quaternion."""

58

59

def quaternion_from_euler(e, i, j, k, extrinsic):

60

"""Convert Euler angles to quaternion."""

61

62

def quaternion_from_axis_angle(a):

63

"""Convert axis-angle representation to quaternion."""

64

65

def quaternion_from_compact_axis_angle(a):

66

"""Convert compact axis-angle to quaternion."""

67

68

def concatenate_quaternions(q1, q2):

69

"""Compose two quaternions (q2 * q1)."""

70

71

def q_conj(q):

72

"""Quaternion conjugate."""

73

74

def q_prod_vector(q, v):

75

"""Rotate vector using quaternion."""

76

77

def quaternion_slerp(start, end, t):

78

"""Spherical linear interpolation between quaternions."""

79

80

def quaternion_integrate(q, omega, dt):

81

"""Integrate angular velocity to update quaternion."""

82

83

def quaternion_diff(q1, q2):

84

"""Difference between quaternions."""

85

86

def quaternion_dist(q1, q2):

87

"""Distance between quaternions."""

88

89

def quaternion_wxyz_from_xyzw(q):

90

"""Convert quaternion from [x,y,z,w] to [w,x,y,z] format."""

91

92

def quaternion_xyzw_from_wxyz(q):

93

"""Convert quaternion from [w,x,y,z] to [x,y,z,w] format."""

94

95

def quaternion_double(q):

96

"""

97

Double quaternion angle (q^2 operation).

98

99

Parameters:

100

- q: array, shape (4,) - Input quaternion

101

102

Returns:

103

- q2: array, shape (4,) - Doubled quaternion

104

"""

105

106

def quaternion_gradient(q, omega):

107

"""

108

Compute quaternion time derivative from angular velocity.

109

110

Parameters:

111

- q: array, shape (4,) - Current quaternion

112

- omega: array, shape (3,) - Angular velocity

113

114

Returns:

115

- dq_dt: array, shape (4,) - Quaternion time derivative

116

"""

117

118

def pick_closest_quaternion(q, quaternions):

119

"""

120

Pick closest quaternion from list (handles q/-q ambiguity).

121

122

Parameters:

123

- q: array, shape (4,) - Reference quaternion

124

- quaternions: array, shape (n, 4) - Candidate quaternions

125

126

Returns:

127

- closest_q: array, shape (4,) - Closest quaternion

128

"""

129

```

130

131

### Axis-Angle Operations

132

133

Operations for axis-angle representations including compact and full forms.

134

135

```python { .api }

136

def check_axis_angle(a, tolerance=1e-6, strict_check=True):

137

"""Validate axis-angle representation."""

138

139

def check_compact_axis_angle(a, tolerance=1e-6, strict_check=True):

140

"""Validate compact axis-angle representation."""

141

142

def norm_axis_angle(a):

143

"""Normalize axis-angle representation."""

144

145

def axis_angle_from_matrix(R):

146

"""Convert rotation matrix to axis-angle."""

147

148

def axis_angle_from_quaternion(q):

149

"""Convert quaternion to axis-angle."""

150

151

def axis_angle_from_two_directions(a, b):

152

"""Compute axis-angle rotation from direction a to b."""

153

154

def compact_axis_angle(a):

155

"""Extract compact axis-angle from full representation."""

156

157

def compact_axis_angle_from_matrix(R):

158

"""Convert rotation matrix to compact axis-angle."""

159

160

def compact_axis_angle_from_quaternion(q):

161

"""Convert quaternion to compact axis-angle."""

162

163

def axis_angle_slerp(start, end, t):

164

"""Spherical linear interpolation between axis-angles."""

165

166

def axis_angle_from_compact_axis_angle(a):

167

"""

168

Compute axis-angle from compact axis-angle representation.

169

170

Parameters:

171

- a: array, shape (3,) - Compact axis-angle: angle * (x, y, z)

172

173

Returns:

174

- a: array, shape (4,) - Axis-angle: (x, y, z, angle)

175

"""

176

177

def norm_compact_axis_angle(a):

178

"""

179

Normalize compact axis-angle representation.

180

181

Parameters:

182

- a: array, shape (3,) - Compact axis-angle

183

184

Returns:

185

- a_norm: array, shape (3,) - Normalized compact axis-angle

186

"""

187

188

def compact_axis_angle_near_pi(a, threshold=1e-4):

189

"""

190

Check if compact axis-angle is near pi (singularity).

191

192

Parameters:

193

- a: array, shape (3,) - Compact axis-angle

194

- threshold: float - Distance threshold for singularity detection

195

196

Returns:

197

- near_pi: bool - True if near singularity

198

"""

199

```

200

201

### Euler Angle Operations

202

203

Operations for Euler angle representations with support for all 24 conventions.

204

205

```python { .api }

206

# Note: No general check_euler function - validation is done per convention

207

208

def norm_euler(e, i, j, k):

209

"""Normalize Euler angles to valid range for given axis sequence."""

210

211

def euler_from_matrix(R, i, j, k, extrinsic, strict_check=True):

212

"""

213

Convert rotation matrix to Euler angles.

214

215

Parameters:

216

- R: array, shape (3, 3) - Rotation matrix

217

- i: int from [0, 1, 2] - First rotation axis (0: x, 1: y, 2: z)

218

- j: int from [0, 1, 2] - Second rotation axis (0: x, 1, y, 2: z)

219

- k: int from [0, 1, 2] - Third rotation axis (0: x, 1: y, 2: z)

220

- extrinsic: bool - Extrinsic (True) or intrinsic (False) convention

221

- strict_check: bool - Enable strict validation

222

223

Returns:

224

- e: array, shape (3,) - Euler angles

225

"""

226

227

def euler_from_quaternion(q, i, j, k, extrinsic):

228

"""Convert quaternion to Euler angles."""

229

230

def euler_near_gimbal_lock(e, i, j, k, threshold=1e-6):

231

"""Check if Euler angles are near gimbal lock."""

232

```

233

234

### Euler Angle Convention Functions (Deprecated)

235

236

Convenience functions for specific Euler angle conventions. **Note: These are deprecated in favor of the general `matrix_from_euler()` and `euler_from_matrix()` functions.**

237

238

```python { .api }

239

# Active matrices from Euler angles - Extrinsic rotations

240

def active_matrix_from_extrinsic_euler_xyz(e):

241

"""Convert extrinsic XYZ Euler angles to rotation matrix (deprecated)."""

242

243

def active_matrix_from_extrinsic_euler_zyx(e):

244

"""Convert extrinsic ZYX Euler angles to rotation matrix (deprecated)."""

245

246

def active_matrix_from_extrinsic_roll_pitch_yaw(rpy):

247

"""Convert roll-pitch-yaw to rotation matrix (deprecated)."""

248

249

# Active matrices from Euler angles - Intrinsic rotations

250

def active_matrix_from_intrinsic_euler_xyz(e):

251

"""Convert intrinsic XYZ Euler angles to rotation matrix (deprecated)."""

252

253

def active_matrix_from_intrinsic_euler_zyx(e):

254

"""Convert intrinsic ZYX Euler angles to rotation matrix (deprecated)."""

255

256

# Euler angles from matrices - Intrinsic conventions

257

def intrinsic_euler_xyz_from_active_matrix(R, strict_check=True):

258

"""Extract intrinsic XYZ Euler angles from rotation matrix (deprecated)."""

259

260

def intrinsic_euler_zyx_from_active_matrix(R, strict_check=True):

261

"""Extract intrinsic ZYX Euler angles from rotation matrix (deprecated)."""

262

263

# Euler angles from matrices - Extrinsic conventions

264

def extrinsic_euler_xyz_from_active_matrix(R, strict_check=True):

265

"""Extract extrinsic XYZ Euler angles from rotation matrix (deprecated)."""

266

267

def extrinsic_euler_zyx_from_active_matrix(R, strict_check=True):

268

"""Extract extrinsic ZYX Euler angles from rotation matrix (deprecated)."""

269

270

# All 24 Euler angle conventions are available as individual functions:

271

# Extrinsic: active_matrix_from_extrinsic_euler_{xyz,xyx,xzx,xzy,yxy,yxz,yzx,yzy,zxy,zxz,zyx,zyz}

272

# Intrinsic: active_matrix_from_intrinsic_euler_{xyz,xyx,xzx,xzy,yxy,yxz,yzx,yzy,zxy,zxz,zyx,zyz}

273

# Matrix to Euler: {intrinsic,extrinsic}_euler_{convention}_from_active_matrix

274

# Recommended: Use matrix_from_euler(e, i, j, k, extrinsic) instead

275

276

def quaternion_from_extrinsic_euler_xyz(e):

277

"""Convert extrinsic XYZ Euler angles to quaternion (deprecated)."""

278

```

279

280

### Vector Utilities

281

282

Utility functions for 3D vector operations.

283

284

```python { .api }

285

def norm_vector(v):

286

"""Normalize vector to unit length."""

287

288

def angle_between_vectors(a, b):

289

"""Compute angle between two vectors."""

290

291

def perpendicular_to_vector(a):

292

"""Find a vector perpendicular to input vector."""

293

294

def vector_projection(a, b):

295

"""Project vector a onto vector b."""

296

297

def perpendicular_to_vectors(a, b):

298

"""Find vector perpendicular to two input vectors."""

299

300

def plane_basis_from_normal(n):

301

"""Generate orthonormal basis vectors for plane from normal."""

302

```

303

304

### Modified Rodrigues Parameters

305

306

Operations for Modified Rodrigues Parameters (MRP) representation.

307

308

```python { .api }

309

def check_mrp(mrp, tolerance=1e-6, strict_check=True):

310

"""Validate Modified Rodrigues Parameters."""

311

312

def norm_mrp(mrp):

313

"""Normalize MRP to avoid singularity."""

314

315

def mrp_from_quaternion(q):

316

"""Convert quaternion to MRP."""

317

318

def mrp_from_axis_angle(a):

319

"""Convert axis-angle to MRP."""

320

321

def quaternion_from_mrp(mrp):

322

"""Convert MRP to quaternion."""

323

324

def axis_angle_from_mrp(mrp):

325

"""Convert MRP to axis-angle."""

326

327

def concatenate_mrp(mrp1, mrp2):

328

"""Compose two MRP representations."""

329

330

def mrp_prod_vector(mrp, v):

331

"""Rotate vector using MRP."""

332

333

def mrp_double(mrp):

334

"""

335

Double MRP rotation angle.

336

337

Parameters:

338

- mrp: array, shape (3,) - Modified Rodrigues Parameters

339

340

Returns:

341

- mrp2: array, shape (3,) - Doubled MRP

342

"""

343

344

def mrp_near_singularity(mrp, threshold=1e-6):

345

"""

346

Check if MRP is near singularity (norm close to 1).

347

348

Parameters:

349

- mrp: array, shape (3,) - Modified Rodrigues Parameters

350

- threshold: float - Distance threshold for singularity

351

352

Returns:

353

- near_singularity: bool - True if near singularity

354

"""

355

```

356

357

### Geometric Algebra Rotors

358

359

Operations for geometric algebra rotor representation.

360

361

```python { .api }

362

def check_rotor(rotor, tolerance=1e-6, strict_check=True):

363

"""Validate rotor representation."""

364

365

def wedge(a, b):

366

"""Wedge (exterior) product of vectors."""

367

368

def geometric_product(a, b):

369

"""Geometric product of multivectors."""

370

371

def rotor_apply(rotor, v):

372

"""Apply rotor rotation to vector."""

373

374

def rotor_reverse(rotor):

375

"""Reverse (conjugate) of rotor."""

376

377

def concatenate_rotors(r1, r2):

378

"""Compose two rotors."""

379

380

def rotor_from_plane_angle(bivector, angle):

381

"""Create rotor from plane and angle."""

382

383

def rotor_from_two_directions(a, b):

384

"""Create rotor aligning direction a to b."""

385

386

def rotor_slerp(start, end, t):

387

"""Spherical linear interpolation between rotors."""

388

389

def plane_normal_from_bivector(bivector):

390

"""Extract plane normal from bivector."""

391

```

392

393

### Visualization and Plotting

394

395

Functions for visualizing rotation representations and coordinate frames.

396

397

```python { .api }

398

def plot_basis(ax, R=None, p=None, s=1.0, strict_check=True, **kwargs):

399

"""

400

Plot coordinate frame basis vectors.

401

402

Parameters:

403

- ax: matplotlib axis - 3D plot axis

404

- R: array, shape (3, 3) - Rotation matrix (default: identity)

405

- p: array, shape (3,) - Origin position (default: origin)

406

- s: float - Scale factor for basis vectors

407

- strict_check: bool - Enable strict validation

408

- kwargs: Additional plotting arguments

409

"""

410

411

def plot_axis_angle(ax, a, p=None, s=1.0, **kwargs):

412

"""

413

Plot axis-angle representation as rotation axis.

414

415

Parameters:

416

- ax: matplotlib axis - 3D plot axis

417

- a: array, shape (4,) - Axis-angle representation

418

- p: array, shape (3,) - Origin position (default: origin)

419

- s: float - Scale factor for axis vector

420

- kwargs: Additional plotting arguments

421

"""

422

423

def plot_bivector(ax, bivector, p=None, s=1.0, **kwargs):

424

"""

425

Plot bivector (oriented plane) in 3D space.

426

427

Parameters:

428

- ax: matplotlib axis - 3D plot axis

429

- bivector: array, shape (3,) - Bivector representation

430

- p: array, shape (3,) - Origin position (default: origin)

431

- s: float - Scale factor for bivector

432

- kwargs: Additional plotting arguments

433

"""

434

```

435

436

### Interpolation

437

438

Spherical linear interpolation (SLERP) operations for smooth rotation interpolation.

439

440

```python { .api }

441

def matrix_slerp(start, end, t):

442

"""Spherical linear interpolation between rotation matrices."""

443

444

def matrix_power(R, t):

445

"""Matrix power operation for rotations."""

446

447

def slerp_weights(t):

448

"""Compute SLERP interpolation weights."""

449

450

def quaternion_slerp(start, end, t):

451

"""Spherical linear interpolation between quaternions."""

452

453

def axis_angle_slerp(start, end, t):

454

"""Spherical linear interpolation between axis-angles."""

455

456

def rotor_slerp(start, end, t):

457

"""Spherical linear interpolation between rotors."""

458

```

459

460

### Random Generation

461

462

Functions for generating random rotations with uniform distribution.

463

464

```python { .api }

465

def random_matrix(random_state=None):

466

"""Generate random rotation matrix."""

467

468

def random_quaternion(random_state=None):

469

"""Generate random unit quaternion."""

470

471

def random_axis_angle(random_state=None):

472

"""Generate random axis-angle representation."""

473

474

def random_compact_axis_angle(random_state=None):

475

"""Generate random compact axis-angle."""

476

477

def random_vector(random_state=None):

478

"""Generate random unit vector."""

479

```

480

481

### Validation and Assertions

482

483

Validation and assertion functions for verifying rotation representations.

484

485

```python { .api }

486

def assert_rotation_matrix(R, *args, **kwargs):

487

"""

488

Raise an assertion if a matrix is not a rotation matrix.

489

490

Checks that R @ R.T = I and det(R) = 1.

491

492

Parameters:

493

- R: array, shape (3, 3) - Matrix to validate

494

- args: Positional arguments passed to assert_array_almost_equal

495

- kwargs: Keyword arguments passed to assert_array_almost_equal

496

"""

497

498

def assert_quaternion_equal(q1, q2, *args, **kwargs):

499

"""Assert that two quaternions are equal (considering q and -q equivalence)."""

500

501

def assert_axis_angle_equal(a1, a2, *args, **kwargs):

502

"""Assert that two axis-angle representations are equal."""

503

504

def assert_compact_axis_angle_equal(a1, a2, *args, **kwargs):

505

"""Assert that two compact axis-angle representations are equal."""

506

507

def assert_euler_equal(e1, e2, i, j, k, *args, **kwargs):

508

"""Assert that two Euler angle representations are equal."""

509

510

def assert_mrp_equal(mrp1, mrp2, *args, **kwargs):

511

"""Assert that two MRP representations are equal."""

512

513

def check_quaternions(Q, unit=True):

514

"""

515

Input validation for multiple quaternions.

516

517

Parameters:

518

- Q: array, shape (n_steps, 4) - Multiple quaternions

519

- unit: bool - Normalize quaternions to unit length

520

521

Returns:

522

- Q: array, shape (n_steps, 4) - Validated quaternions

523

"""

524

525

def check_skew_symmetric_matrix(S):

526

"""Validate that matrix is skew-symmetric (S = -S.T)."""

527

528

def check_rot_log(S):

529

"""Validate rotation logarithm representation."""

530

531

def quaternion_requires_renormalization(q, tolerance=1e-3):

532

"""Check if quaternion needs renormalization."""

533

534

def matrix_requires_renormalization(R, tolerance=1e-3):

535

"""Check if rotation matrix needs renormalization."""

536

```

537

538

### Angle-Based Rotations

539

540

Functions for creating rotations from simple angle rotations around coordinate axes.

541

542

```python { .api }

543

def norm_angle(a):

544

"""

545

Normalize angle to (-pi, pi] range.

546

547

Parameters:

548

- a: float or array - Angle(s) in radians

549

550

Returns:

551

- a_norm: float or array - Normalized angle(s)

552

"""

553

554

def active_matrix_from_angle(basis, angle):

555

"""

556

Compute active rotation matrix from rotation about basis vector.

557

558

Parameters:

559

- basis: int from [0, 1, 2] - Rotation axis (0: x, 1: y, 2: z)

560

- angle: float - Rotation angle in radians

561

562

Returns:

563

- R: array, shape (3, 3) - Active rotation matrix

564

"""

565

566

def passive_matrix_from_angle(basis, angle):

567

"""

568

Compute passive rotation matrix from rotation about basis vector.

569

570

Parameters:

571

- basis: int from [0, 1, 2] - Rotation axis (0: x, 1: y, 2: z)

572

- angle: float - Rotation angle in radians

573

574

Returns:

575

- R: array, shape (3, 3) - Passive rotation matrix

576

"""

577

578

def quaternion_from_angle(basis, angle):

579

"""

580

Compute quaternion from rotation about basis vector.

581

582

Parameters:

583

- basis: int from [0, 1, 2] - Rotation axis (0: x, 1: y, 2: z)

584

- angle: float - Rotation angle in radians

585

586

Returns:

587

- q: array, shape (4,) - Unit quaternion (w, x, y, z)

588

"""

589

```

590

591

### Mathematical Operations

592

593

Advanced mathematical operations for rotation analysis.

594

595

```python { .api }

596

def cross_product_matrix(v):

597

"""Convert vector to skew-symmetric matrix."""

598

599

def rot_log_from_compact_axis_angle(a):

600

"""Convert compact axis-angle to rotation logarithm."""

601

602

def left_jacobian_SO3(omega):

603

"""Left Jacobian for SO(3) group."""

604

605

def left_jacobian_SO3_inv(omega):

606

"""Inverse left Jacobian for SO(3)."""

607

608

def left_jacobian_SO3_series(omega):

609

"""Left Jacobian for SO(3) using series expansion."""

610

611

def left_jacobian_SO3_inv_series(omega):

612

"""Inverse left Jacobian for SO(3) using series expansion."""

613

614

def robust_polar_decomposition(A):

615

"""Robust polar decomposition of matrix."""

616

```

617

618

### Constants

619

620

Mathematical constants for rotation operations.

621

622

```python { .api }

623

eps: float # Small epsilon value for numerical computations

624

unitx: np.ndarray # Unit vector [1, 0, 0]

625

unity: np.ndarray # Unit vector [0, 1, 0]

626

unitz: np.ndarray # Unit vector [0, 0, 1]

627

q_i: np.ndarray # Quaternion i basis element

628

q_j: np.ndarray # Quaternion j basis element

629

q_k: np.ndarray # Quaternion k basis element

630

q_id: np.ndarray # Identity quaternion [1, 0, 0, 0]

631

a_id: np.ndarray # Zero axis-angle representation

632

R_id: np.ndarray # 3x3 identity rotation matrix

633

p0: np.ndarray # Origin point [0, 0, 0]

634

```

635

636

## Usage Examples

637

638

### Basic Rotation Conversions

639

640

```python

641

import numpy as np

642

import pytransform3d.rotations as pr

643

644

# Convert Euler angles to rotation matrix (XYZ convention)

645

euler = [0.1, 0.2, 0.3] # roll, pitch, yaw

646

R = pr.matrix_from_euler(euler, 0, 1, 2, True) # XYZ extrinsic

647

648

# Convert to quaternion

649

q = pr.quaternion_from_matrix(R)

650

651

# Convert to axis-angle

652

a = pr.axis_angle_from_quaternion(q)

653

654

# Verify round-trip conversion

655

R_reconstructed = pr.matrix_from_axis_angle(a)

656

assert np.allclose(R, R_reconstructed)

657

```

658

659

### Quaternion Composition

660

661

```python

662

import pytransform3d.rotations as pr

663

664

# Create two rotations

665

q1 = pr.quaternion_from_euler([0.1, 0, 0], 0, 1, 2, True) # X rotation

666

q2 = pr.quaternion_from_euler([0, 0.2, 0], 0, 1, 2, True) # Y rotation

667

668

# Compose rotations (q2 applied after q1)

669

q_composed = pr.concatenate_quaternions(q1, q2)

670

671

# Interpolate between rotations

672

t = 0.5 # halfway

673

q_interp = pr.quaternion_slerp(q1, q2, t)

674

```

675

676

### Vector Rotation

677

678

```python

679

import numpy as np

680

import pytransform3d.rotations as pr

681

682

# Define rotation and vector

683

q = pr.quaternion_from_euler([0, 0, np.pi/4], 0, 1, 2, True) # Z rotation

684

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

685

686

# Rotate vector

687

v_rotated = pr.q_prod_vector(q, v)

688

print(f"Original: {v}")

689

print(f"Rotated: {v_rotated}")

690

```