How Do I Move a Set of (x,y,z) Points so they Align with the X-Y Plane?

조회 수: 20 (최근 30일)
Bryan Sinkovec
Bryan Sinkovec 2015년 11월 18일
댓글: Preetham Manjunatha 2022년 4월 20일
Hi all,
I have a large set of (x,y,z) data points creating a “bumpy” (non-flat) surface that I am trying to get to “flatten out” onto the x-y plane without losing any integrity of the surface features.
I tried following the suggestion here
but the asker was specific to ask for their data to follow along the x axis. I am trying to get my data to fall along the x-y plane in whatever angle it originates at. It does not necessarily need to be centered at zero or anything (in my example it is, but I would not like it to), just flattened to the x-y plane using only the given (x,y,z) data.
With the help of the above suggestion, I’ve tried this code:
XYZ = [11 11 11
12 12 13
13 13 12
14 14 15
15 15 17
16 16 17
17 17 18
18 18 18
19 19 20
10 12 12
11 13 11
12 14 13
13 15 14
14 16 19
15 17 13
16 18 15
17 19 18
18 20 17
12 10 11
13 11 13
14 12 14
15 13 12
16 14 17
17 15 19
18 16 18
19 17 15
20 18 19];
X = XYZ(:,1);
Y = XYZ(:,2);
Z = XYZ(:,3);
% Plot the raw data
scatter3(X,Y,Z,'b','LineWidth',5) % blue dots
xlabel('X-Axis','FontSize',14,'FontWeight','bold')
ylabel('Y-Axis','FontSize',14,'FontWeight','bold')
zlabel('Z-Axis','FontSize',14,'FontWeight','bold')
xyz0=mean(XYZ);
A=bsxfun(@minus,XYZ,xyz0); % center the data at zero
% Find the direction of most variance using SVD and rotate the data to make
% that the x-axis
[U,S,V]=svd(A,0);
A_rot = A*V; % V(:,1) is the direction of most variance
hold on
scatter3(A_rot(:,1),A_rot(:,2),A_rot(:,3),'g','LineWidth',5); % green dots
This code centers the data at (0,0,0), flattens it out, and rotates it in the direction of most variance (close to the x-axis) while making use of the svd function. I’m looking to see if I can keep the plot in the same position at its same x-y position, but flatten it down from its z position. I don’t believe I can simply adjust the data by a specific angle, because other surfaces may not be at a nice easy angle and I will not always know what the angle is. It simply needs to be moved down with the same surface features into the x-y plane.
If anybody can help me out on this, it would be very much appreciated, and thank you in advance.

답변 (2개)

Preetham Manjunatha
Preetham Manjunatha 2021년 7월 23일
Fit a oriented bounding box and obtain the orientation of that bounding box and invert the rotation matrix of the Euler angles. This will produce a re-orientated point cloud that is parallel to XY, YZ and XZ planes. If you need to rotate again, Eulaer angles [phi theta psi] can be used, for example [90 0 0] or [-90 0 0] and others. The program which does this can be downloaded at 3DspaceTile.
This program actually divides the 3D space, one can use the divisions as [1 1 1] in XYZ directions. Same program can reorient the point clouds to be parallel to XY, YZ and XZ planes. For the program requirements, please visit the GitHub page.
Hope this helps someone in future.
  댓글 수: 3
Bruno Luong
Bruno Luong 2022년 4월 20일
편집: Bruno Luong 2022년 4월 20일
@TB I don't know about your code, but here is three rotations to bring the data to resp YZ, ZX, and XY plane
[Q,~] = qr(randn(3));
n = 500;
sigma = 0.01;
ptCloudOriginal = (rand(n,3).*[1 1 0] + sigma*randn(n,3)) * Q;
[~,~,V]=svd(ptCloudOriginal-mean(ptCloudOriginal,1),0);
N = V(:,3);
close all
scatter3(ptCloudOriginal(:,1),ptCloudOriginal(:,2),ptCloudOriginal(:,3));
hold on
for i=1:3
axisi = accumarray(i,1,[3 1]);
a=cross(N,axisi);
T=makehgtform('axisrotate', a, -atan2(norm(a),N(i)));
R=T(1:3,1:3);
XYZ_rot = ptCloudOriginal*R;
scatter3(XYZ_rot(:,1),XYZ_rot(:,2),XYZ_rot(:,3),'marker','.');
end
axis equal
Preetham Manjunatha
Preetham Manjunatha 2022년 4월 20일
@TB could you please share before and after transformed point clouds?

댓글을 달려면 로그인하십시오.


Bruno Luong
Bruno Luong 2022년 4월 20일
편집: Bruno Luong 2022년 4월 20일
I guess what you describe as "but flatten it down from its z position"" or "move down" is that you want to rotate about the axis that is parallel to x-y plane (?). In this case try this code
NOTE: incidently this is also the most economical way (smalest roration angle) to rotate the point cloud to be parallel to x-y plane
% XYZ = [11 11 11
% 12 12 13
% 13 13 12
% 14 14 15
% 15 15 17
% 16 16 17
% 17 17 18
% 18 18 18
% 19 19 20
% 10 12 12
% 11 13 11
% 12 14 13
% 13 15 14
% 14 16 19
% 15 17 13
% 16 18 15
% 17 19 18
% 18 20 17
% 12 10 11
% 13 11 13
% 14 12 14
% 15 13 12
% 16 14 17
% 17 15 19
% 18 16 18
% 19 17 15
% 20 18 19];
[Q,~] = qr(randn(3));
n = 500;
sigma = 0.02;
XYZ = (rand(n,3).*[1 1 0] + sigma*randn(n,3)) * Q;
X = XYZ(:,1);
Y = XYZ(:,2);
Z = XYZ(:,3);
xyz0=mean(XYZ,1);
A=XYZ-xyz0; % center the data at zero
% Find the direction of most variance using SVD and rotate the data to make
% that the x-axis
[~,~,V]=svd(A,0);
a=cross(V(:,3),[0;0;1]);
T=makehgtform('axisrotate', a, -atan2(norm(a),V(3,3)));;
R=T(1:3,1:3);
A_rot = A*R;
A_rot = A_rot + [xyz0(1) xyz0(2) 0]; % move so the centers are aligned in z-diection
% Plot the raw data
close all
scatter3(X,Y,Z,'b','LineWidth',2) % blue dots
hold on
scatter3(A_rot(:,1),A_rot(:,2),A_rot(:,3),'g','LineWidth',2); % green dots
xlabel('X-Axis','FontSize',14,'FontWeight','bold')
ylabel('Y-Axis','FontSize',14,'FontWeight','bold')
zlabel('Z-Axis','FontSize',14,'FontWeight','bold')
axis equal

카테고리

Help CenterFile Exchange에서 Surface and Mesh Plots에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by