I’m interested in using `ndarray`

with `nalgebra`

to rotate a point cloud `points: Array3`

where `points.dim`

is `(3, height, width)`

by a rotation `rot: na::Rotation3`

. Basically the idea is to treat `points`

as a matrix of size `(3, height * width)`

and do `rot * points`

.

So far I have this, but I’m not sure if it’s efficient.

```
pub fn rotate(rot: &na::Rotation3<f64>, points: &Array3<f64>) -> anyhow::Result<Array3<f64>> {
let (_, height, width) = points.dim();
let slice = na::DMatrixSlice::from_slice_with_strides(
points
.as_slice()
.ok_or(anyhow!("points array malformed (not contiguous?)"))?,
height * width,
3,
1,
height * width,
);
let rotated = slice * rot.transpose();
let rotated_array: Array3<f64> =
ArrayView3::from_shape((3, height, width), rotated.as_slice())?.to_owned();
// is there a way to avoid the copy from the nalgebra to the array?
Ok(rotated_array)
}
```

Alternatively instead of making a `na::DMatrixSlice`

out of my `Array3`

, I could make an `ndarray::ArrayView`

out of the `Rotation3`

or any 3 x 3 matrix and use ndarray linear algebra to perform the multiplication…

btw for some motivation to rotate this sort of Array3 of size `(3, height, width)`

by a `na::Rotation3`

, this is a common scenario when:

- applying a color calibration matrix to rgb or whatever color values (so instead of Rotation3 you’d just have a 3 x 3 matrix), e.g. to convert between different linear color spaces
- transforming structured point clouds (from a lidar such as the iPhone 12 lidar or an Ouster lidar or depth sensor like the Kinect)
- transforming the vertices of a virtual geometry image (recently popularized by Unreal Engine 5’s “Nanite”)