Convert rotations given as quaternions to rotation matrices. Args: quaternions: quaternions with real part first, as tensor of shape (..., 4). Returns: Rotation matrices as tensor of shape (..., 3, 3).
(quaternions: torch.Tensor)
| 474 | |
| 475 | |
| 476 | def quaternion_to_matrix(quaternions: torch.Tensor) -> torch.Tensor: |
| 477 | """ |
| 478 | Convert rotations given as quaternions to rotation matrices. |
| 479 | |
| 480 | Args: |
| 481 | quaternions: quaternions with real part first, |
| 482 | as tensor of shape (..., 4). |
| 483 | |
| 484 | Returns: |
| 485 | Rotation matrices as tensor of shape (..., 3, 3). |
| 486 | """ |
| 487 | r, i, j, k = torch.unbind(quaternions, -1) |
| 488 | # pyre-fixme[58]: `/` is not supported for operand types `float` and `Tensor`. |
| 489 | two_s = 2.0 / (quaternions * quaternions).sum(-1) |
| 490 | |
| 491 | o = torch.stack( |
| 492 | ( |
| 493 | 1 - two_s * (j * j + k * k), |
| 494 | two_s * (i * j - k * r), |
| 495 | two_s * (i * k + j * r), |
| 496 | two_s * (i * j + k * r), |
| 497 | 1 - two_s * (i * i + k * k), |
| 498 | two_s * (j * k - i * r), |
| 499 | two_s * (i * k - j * r), |
| 500 | two_s * (j * k + i * r), |
| 501 | 1 - two_s * (i * i + j * j), |
| 502 | ), |
| 503 | -1, |
| 504 | ) |
| 505 | return o.reshape(quaternions.shape[:-1] + (3, 3)) |
| 506 | |
| 507 | def _copysign(a: torch.Tensor, b: torch.Tensor) -> torch.Tensor: |
| 508 | """ |
no outgoing calls
no test coverage detected