You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
Converting 3D to 2D cloud of points
6 views (last 30 days)
Show older comments
I am trying to convert a set of data which is a cloud of points from 3D to 2D, I am using this code:
% Function from 3D to 2D
function [D,R,T]=dimred(X)
T = repmat(mean(X),[size(X,1),1]);
XX = X-T;
[R,N]=eig(XX'*XX);
D=XX*R;
D=D(:,2:end);
Q=[zeros(size(D,2),1) eye(size(D,2))];
R=Q*R';
return
% 3D to 2D
[nodes_2D,R,T]=dimred(newnodes1) % R = rot matrix, T = Translation matrix
The data correctly converts to 2D, in this case, looking at the image the 3D points are rotated to the left, but for a different cloud of points it rotates it to the right. My question is the next, is there any way of forcing to apply the rotation always in the same direction? (without manually reversing the 2D red plot).
I have attached the figure and the .mat containing the cloud of points in 3D.
Thank you for any help.
10 Comments
Walter Roberson
on 30 Jun 2018
I notice you use the eigenvectors as returned. Any scalar multiple of an eigenvector acts the same way, including negative multiples. As I do not see any code in there to explicitly normalize, I wonder if the difficulty you are facing is that some of your eigenvectors just happen to be coming out with the negative of the sign you are expecting for the purposes of rotation ?
Alfonso
on 30 Jun 2018
Edited: Alfonso
on 30 Jun 2018
Hello Walter, you are right, the eigenvectors are in SOME cases coming up with the opposite sign that I want them to, and I don't know why this happens, it seems that depending on the initial 3D data, it gets flattened to the left or to the right. My objective is to always get the same "2D view" of my 3D cloud of points (always flattened to the right for example).
These are the 2 only possibilities of 2D result from the 3D blue data. Currently for this dataset, I obtain the red 2D plot, but I want the magenta one which I have been able to plot reversing the R (rotation matrix). The problem as I said, is that the result obtained (red or magenta) changes for each 3D dataset, so I don't know how to detect before seeing the plots if the rotation has been the one I want (magenta) or not.
I hope my explanation does not look too messy,
Thank you
Walter Roberson
on 30 Jun 2018
Edited: Walter Roberson
on 30 Jun 2018
Can you divide each eigenvector by its first non-zero element, so that the leading entries are all 0 or positive ?
Alfonso
on 30 Jun 2018
For this 3D dataset using the code I posted I get the following:
% R = Eigenvalues
R =
0.0600 0.3950 -0.9167
0.4589 0.8047 0.3768
% N = Right Eigenvectors
N =
1.0e+05 *
0.0000 0 0
0 2.4094 0
0 0 3.1734
So right eigenvectors result in 0/+ when dividing by the 1st element, did you mean this or am I getting confused?
I also uploaded the .mat file with the 3D data in the initial post.
Walter Roberson
on 30 Jun 2018
I meant like
for K = 1 : size(R,2)
firstR = find(R(:,K),1,'first');
R(:,K) = R(:,K) ./ firstR;
end
... Of course there are ways to vectorize this, but it is simply not worth the trouble.
Walter Roberson
on 30 Jun 2018
Perhaps it is only one particular one of the dimensions that needs to be positive and you can divide by the sign of that particular dimension?
Note: your comments are reversed above, R is the eigenvectors and diag(N) are the eigenvalues.
Alfonso
on 30 Jun 2018
When I try to transform from 3D to 2D several datasets, in some of them I get the correct 2D view but the ones I don't get correctly are always reversed in Y. So if for example I do this:
R(:,2) = R(:,2) * -1;
And then transform to 2D, I obtain the correct 2D view (in the case the first result was the wrong view).
Maybe the sign of one of the values of the eigenvector corresponding to Y axis determines if it is flattened to the right or left, I have to take a look, but could this be?
Walter Roberson
on 30 Jun 2018
for K = 1 : size(R,2)
s = sign(R(2,K));
R(:,K) = R(:,K) .* s;
end
You need to transform the entire eigenvector.
Alfonso
on 1 Jul 2018
Hello Walter, it does not seem to work. For a 3D dataset 1 it flattens it to the left side, whereas for a 3D dataset 2 of the same plane as dataset 1 it flattens it to the right (same behaviour I had).
3D dataset1:
3D dataset2:
Accepted Answer
Matt J
on 30 Jun 2018
Edited: Matt J
on 30 Jun 2018
normal=null(XX);
normal=normal(:,end)*sign(normal(1,end));
rotaxis=-cross([0,0,1].',normal);
theta=asind(norm(rotaxis));
[D,R,~] = AxelRot(XX.', theta, rotaxis, []);
11 Comments
Alfonso
on 30 Jun 2018
Edited: Alfonso
on 30 Jun 2018
Hello Matt, as you are using XX I assume the code you wrote must go inside the function I posted after: XX = X-T?
I have tried this:
X = newnodes1;
T = repmat(mean(X),[size(X,1),1]);
XX = X-T;
normal=null(XX);
normal=normal(:,end)*sign(normal(1,end));
rotaxis=-cross([0,0,1].',normal);
theta=asind(norm(rotaxis));
[2D_data,R,~] = AxelRot(XX.', theta, rotaxis, []);
but the transformation from 3D to 2D does nor perform correctly, surely I am misunderstanding something.
Matt J
on 30 Jun 2018
Edited: Matt J
on 30 Jun 2018
"2D_data" is not a valid Matlab variable name. That will surely throw an error.
Try this,
X = newnodes1;
T = repmat(mean(X),[size(X,1),1]);
XX = X-T;
normal=null(XX);
normal=normal(:,end);
rotaxis=cross(normal,[0,0,1].');
s=-sign(mean(sign(rotaxis(1:2)))); %decide which way is "left"
rotaxis=s*rotaxis;
theta=acosd(s*normal(3));
[D,R,~] = AxelRot(XX.', theta, rotaxis, []);
D=D(1:2,:).';
Alfonso
on 1 Jul 2018
Edited: Alfonso
on 1 Jul 2018
Hello Matt, I am testing it with all my 3D datasets right now. If I have understood correctly, if I mantain the sign of 's' as, say +, it will always force the rotation to go the same way, so the 3D data will always flatten in this direction (what is what I'm looking for),
I'll let you know when I finish testing the datasets,
Thank you.
Alfonso
on 1 Jul 2018
Edited: Alfonso
on 1 Jul 2018
Works perfectly as I want to with the 3D dataset I initially posted and also work right for 3D datasets that belong to the same plane as the initial dataset, but I have tried with a different 3D cloud of points that belong to another plane and all values in the resulting 2D data are NaN, do you know what might be the problem?
Seems to me maybe the problem is in here (I am not sure)
s=-sign(mean(sign(rotaxis(1:2))));
rotaxis(1:2)=
0.0000
-0.4472
% So the sign will be the mean between 1 and -1, which is 0
rotaxis=s*rotaxis; % will give [0;0;0]
also warning messages appear:
Warning: Matrix is singular, close to singular or badly scaled. Results may be inaccurate. RCOND = NaN.
> In AxelRot (line 94)
> In AxelRot (line 63)
I have attached the 3D dataset,
Thank you.
Matt J
on 1 Jul 2018
Edited: Matt J
on 1 Jul 2018
You need to give us a more precise and general definition of "rotate to the left". Which way is "left", in general, if the 3D orientation of the cloud can be arbitrary? Perhaps this?
normal=null(XX);
normal=normal(:,end);
rotaxis=cross(normal,[0,0,1].');
[~,idx]=max(abs(rotaxis));
s=-sign(rotaxis(idx)); %decide which way is "left"
Alfonso
on 1 Jul 2018
I will try this code. In order to understand what I mean, I have attached two figures, one represents que 3D data converted to 2D rotated to the "left" and the other figure is rotated to the "right". Manually rotate the figures and that way I think you will know what I mean by left/right.
Thank you.
Matt J
on 1 Jul 2018
Edited: Matt J
on 1 Jul 2018
OK, well see if you like my last implementation.
However, your attached .fig files don't clear up the ambiguity. Your notions of "right" and "left" appear to depend arbitrarily on the plot camera angle. For example, if we were to rotate the plot perspective 180 degrees about the z-axis, so that we were viewing the original blue points from the opposite side, then left would become right and right would become left.
To put it another way, suppose your blue points lay entirely in the xz-plane. I know you want the points rotated clockwise all the time about a consistent axis, and I know that axis is either the positive x-axis or the negative x-axis, but which one is it? Similarly, what about if the data is in the yz-plane. Do we rotate clockwise about y or about -y?
Alfonso
on 1 Jul 2018
Edited: Alfonso
on 1 Jul 2018
Yes, it is quite ambiguous, but it's hard to explain. Look at this view, I want the the 2D data to be like the 3D data in this view. The result is the magenta plot, which is like if you pushed the top part of the blue plot with your hand about 90º. This is the 2D "view" I am looking for for all my 3D datasets.
I have tried your new code and seems to work right. I have 3 type of 3D data planes, for one I get the 2D view I want with - sign for the second one with + sign, and the third one is a horizontal plane so I just put the angle of rotation to 0 and I get the correct view.
I will test it with more 3D datasets of this 3 planes to see if for all datasets of the same plane it satisfies the same sign (-/+), but at the moment it looks like it works just as I wanted.
for example this is what I should get (a general sign for all datasets of the same plane):
All 3D datasets of plane1: correct view with sign -
All 3D datasets of plane2: correct view with sign +
Matt J
on 2 Jul 2018
Edited: Matt J
on 2 Jul 2018
which is like if you pushed the top part of the blue plot with your hand about 90º
That is not consistent with your original post. In your original post we were pulling, not pushing. And the point to be clarified is still how you decide whether to push or pull.
More Answers (0)
See Also
Categories
Find more on Point Cloud Processing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)