Vectorized rotation of 3D gridded volumes

3 vues (au cours des 30 derniers jours)
Alexander Laut
Alexander Laut le 24 Avr 2019
Commenté : Guillaume le 1 Mai 2019
Problem
I understand that in general, if I define a 3D rotation matrix such as:
R = [
1,0,0;
0,cos(theta),-sin(theta);
0,sin(theta),cos(theta)
]
Then I can rotate a pointcloud pts where:
pts = [x(:), y(:), z(:)]
where x, y, z are datasets of arbitrary size and
by:
pts = pts*R
then:
[xp, yp, zp] = deal(pts(:,1), pts(:,2), pts(:,3))
I can then reshape the output vectors using
xp = reshape(xp, size(x))
yp = reshape(yp, size(y))
zp = reshape(zp, size(z))
Is there a more generalized way for matlab to apply a 3D rotation as described with R (3 x 3 matrix) such that I can for instance apply the rotation to an X, Y, Z volume (3 x m x n) in a single operation? For instance, say I define my X, Y, Z as a meshgrid so that each X, Y, Z is a m x n x p volume, can I do somethine like this
V = cat(3, X, Y, Z)
V = V*R
I would think an operation like this would be much faster and cleaner to implement than unloading into vectors and reshaping afterwards.
Attempt at Solution
[Lx,Ly, dL] = deal(10,20,1);
x = linspace(-Lx/2, Lx/2, Lx/dL);
y = linspace(-Ly/2, Ly/2, Ly/dL);
[X,Y] = meshgrid(x,y);
Z = zeros(size(X));
% Convert to pointcloud (should be optional?)
%%{
X = X(:);
Y = Y(:);
Z = Z(:);
%}
V = cat(3, X, Y, Z);
TH = [pi/4, 0, 0]; % define rotation about x, then y, then z (radians)
% Basic Rotations (https://en.wikipedia.org/wiki/Rotation_matrix)
Rx = [1,0,0; 0,cos(TH(1)),-sin(TH(1)); 0,sin(TH(1)),cos(TH(1))];
Ry = [cos(TH(2)),0,sin(TH(2)); 0,1,0; -sin(TH(2)),0,cos(TH(2))];
Rz = [cos(TH(3)),-sin(TH(3)),0; sin(TH(3)),cos(TH(3)),0; 0,0,1];
R = Rx*Ry*Rz; % generalize rotation matrix for 3D data
V = V*R; % generalized rotation operation
surf(V(:,:,1), V(:,:,2), V(:,:,3),'facecolor','none','edgecolor','black')

Réponses (1)

Matt J
Matt J le 24 Avr 2019
Modifié(e) : Matt J le 24 Avr 2019
Maybe this is what you're looking for?
[XYZ{1:3}] = meshgrid(x,y,0);
V = cat(4, XYZ{:}); sz=size(V);
V = reshape(V,[],3)*R; % generalized rotation operation
V = reshape(V,sz);
surf(V(:,:,:,1), V(:,:,:,2), V(:,:,:,3),'facecolor','none','edgecolor','black')
  5 commentaires
Matt J
Matt J le 1 Mai 2019
Modifié(e) : Matt J le 1 Mai 2019
They wouldn't have made it,
if they didn't want you to use it...
Guillaume
Guillaume le 1 Mai 2019
I'm curious how "clean" is something like that considered to an experienced MATLAB user
Matt's answer is exactly how I would have coded it (except with ndgrid instead of meshgrid) and I certainly use expansion of cell arrays (and structures) in comma separated lists very often. It's efficient and there's nothing unclean about it.

Connectez-vous pour commenter.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by