Skip to content

Commit b26fa1c

Browse files
author
peng.li24
committed
Add Rotation::from_euler + as_matrix, resolve issue 001
- scipy/transform.h: add as_matrix(T* m9) public method (quaternion→matrix) Uses scipy's exact formulas: R[i,j] = f(x²,y²,z²,w²,xy,zw,...) - scipy/transform.h: add from_euler(seq, angle) single-axis (std::sin/cos) - scipy/transform.h: add from_euler(seq, angles[]) multi-axis with correct extrinsic (lowercase, reversed compose) / intrinsic (uppercase) handling matching scipy's _rotation.pyx Hamilton-product composition order - pycpp/transform_py.h: add from_euler() Python wrapper that delegates to scipy.Rotation.from_euler (numpy/SVML sin/cos → exact quaternion) - pycpp/transform_py.h: add as_matrix() Python wrapper calling C++ arithmetic with exact quaternion → 0-ULP full pipeline - tests/test_all.py: TestFromEulerAsMatrix (38 tests, 960 assertions, all 0 ULP) Key regression: from_euler(z, 5.837569e-06).as_matrix() → 0 ULP Covers: near-zero yaw, all 6 extrinsic seqs ×100, intrinsic XYZ/ZYX ×100, full roundtrip from_euler→as_matrix→from_matrix→as_euler - issue/001: marked RESOLVED
1 parent 7a9ce94 commit b26fa1c

5 files changed

Lines changed: 1251 additions & 3 deletions

File tree

README.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,19 @@ scipy::ndimage::gaussian_filter1d(src, out.data(), n, sigma);
4848
// Signal — median filter
4949
scipy::signal::medfilt(src, dst.data(), n, kernel_size);
5050

51-
// Transform — Rotation (from_matrix + as_euler)
51+
// Transform — Rotation (from_matrix, from_euler, as_euler, as_matrix)
5252
auto rot = scipy::spatial::transform::Rotation<double>::from_matrix(R);
5353
auto euler = rot.as_euler_vec("xyz"); // returns [rx, ry, rz]
54+
55+
// from_euler + as_matrix — single axis (key use case: ego yaw)
56+
double m9[9];
57+
auto rot_z = scipy::spatial::transform::Rotation<double>::from_euler("z", yaw);
58+
rot_z.as_matrix(m9); // 3×3 row-major rotation matrix
59+
60+
// from_euler — multi-axis extrinsic / intrinsic
61+
double angles[3] = {rx, ry, rz};
62+
auto rot_xyz = scipy::spatial::transform::Rotation<double>::from_euler("xyz", angles);
63+
rot_xyz.as_matrix(m9);
5464
```
5565
5666
### Dependencies
@@ -84,7 +94,7 @@ including extreme values (±inf, NaN, ±0.0, subnormals, saturation inputs).
8494
| `spatial` | pure C++ / scipy ckdtree | cdist, KDTree |**0 ULP** |
8595
| `ndimage` | Python numpy kernel | gaussian_filter1d |**0 ULP** |
8696
| `signal` | sort-based median | medfilt |**0 ULP** |
87-
| `transform` | delegates to scipy | Rotation |**0 ULP** |
97+
| `transform` | delegates to scipy | Rotation.from_matrix, from_euler, as_euler, as_matrix |**0 ULP** |
8898

8999
Full per-test ULP report: [`doc/ulp_report.csv`](doc/ulp_report.csv)
90100
(Auto-generated by `pytest tests/test_all.py`, see [doc/ulp_report.md](doc/ulp_report.md) for summary)

0 commit comments

Comments
 (0)