Create a structure from discrete column vectors or a 3 x n matrix composed of column vectors

Hi
I'm trying to build a structure consisting of elements which are column vectors representing x, y, z points. So far, I have written the following code, which indexes arrays representing x, y, z positions of points from a structure called 'data' (derived from a .ply 3d graphics file) and rearranges them into a 3 x n matrix:
% orders vertex data from structure into column vectors
x = data.vertex.x
y = data.vertex.y
z = data.vertex.z
% vertically concatenates x, y, z to form a 3 x n matrix stored in the
% structure, verts
verts = horzcat(x, y, z)
%Sequentially indexes PX PY PZ into a 3 x n matrix where columns are x y z
%components of position vectors
for i=1:length(x)
vertsnew(:,i)=[x(i);y(i);z(i)];
end
This creates a matrix of the form:
3.7427 3.74984 1.38903
4.7384 3.76483 8.76289
9.6389 9.62843 5.78290 .............
I want to create a structure where each column vector in this array is a seperate element. I thought the following might do the trick:
vertz=struct();
for k=1:size(x)
Vk = [vertsnew(1,k)];
vertz.(['VZ' num2str(k)])=Vk;
end
But this results in a structure with x, y, z arranged sequentially as individual elements. E.g:
vertz.VZ.1 = 3.7427
vertz.VZ.2 = 4.7384
vertz.VZ.3 = 9.6389
I am able to create individual column vectors using:
%Orders arrays, into discrete column vectors
for i=1:length(x)
assignin('base',['vertv' num2str(i)],[x(i);y(i);z(i)])
end
E.g.
vertv1 = 3.7427
vertv2 = 4.7384
etc
Though I am unsure how to obtain the desired structure from these seperate arrays. Any help would be greatly appreciated.
Thomas

6 Kommentare

Don't do it! Keep the data in 3xn form and work with that.
Hi Matt
What is the advantage of keeping the position vectors stored in a matrix? The next phase in the workflow would be to concatenate a a single array '0' to the bottom of each column vector and multiply by a transformation matrix (incidently, calculated using a modified version of your implementation of Horn's method (brilliantly useful by the way!). If I was to keep the 3 x 2 matrix, I think I could easily perform the horzcat, but am unsure how to multiply each column of the matrix by the 4 x 4 transformation matrix. Any suggestions would be most appreciated.
Thanks
Thomas
Thomas,
The operations you describe are what matrices were made for, and seem much harder to do if you split all the columns into fields of a struct.
If you have a 3xn matrix, vertsnew, you can pad zeros along the bottom of all of its columns as easily as
vertsnew4xn=[vertsnew;zeros(1,n)];
You can then apply a transform matrix to all columns just by pre-multiplying the whole 4xn array by the transformation matrix.
vertsnewnew = A*vertsnew4xn;
It sounds a little weird, by the way, that you would append a '0' to the bottom. If you do this, the final column of A contributes nothing to the transform and you can just as easily omit it and use the original 3xn array,
vertsnewnew=A(:,1:end-1)*vertsnew;
Thanks Matt. Yes, I see what you mean about working with structs. I have been doing this for similar operations and it does make the coding a little bit clumsy, usually lots of struct2cell etc. I will have a go at playing with the 3 x n matrices. By the way, the reason I was going to add the 0 was so that the column vectors 'agree' with the 4 x 4 transformation matrix. I thought that the multiplication would not work otherwise. Is this not correct?
Thanks again.
If you're talking about a 4x4 rototranslation matrix, then you would want to pad along the bottom with 1s instead of 0s. Instead of using a 4x4 matrix, a more efficient way to perform a rototranslation (probably) is
out = bsxfun(@plus,R*vertsnew,t)
because this way MATLAB doesn't have to copy all of the data in vertsnew to a new 4xn array. That would matter mainly if n is large.
Apologies, I forgot the bottom row is 0 0 0 1. Thanks for your advice Matt. I'll have to have a look up the bsxfun function as I'm not familiar with it. The reason I was to use a 4x4 matrix is that it is output by your absor() function: very useful to me for introducing arbitrerally oriented and scaled spatial data into a target coordinate system. Though I'm sure you know much more about that than I do! I may need the more efficient option though as I'm processing point datasets containing tens to hundreds of thousands of points (though I do have access to some pretty decent hardware to counter this).
Thomas

Melden Sie sich an, um zu kommentieren.

 Akzeptierte Antwort

y=[3.7427 3.74984 1.38903
4.7384 3.76483 8.76289
9.6389 9.62843 5.78290]
for k=1:size(y,2)
vertz.(sprintf('VZ%d',k))=y(:,k)
end

2 Kommentare

Thanks Azzi The code works perfectly, though as Matt has pointed out, perhaps this is not the best data structure for my purposes.
Shukran
Thomas
I agree with him that is not the best way, but at the end you are the only person to decide how to do it. Also, whatever you do, there is always a better way!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Produkte

Community Treasure Hunt

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

Start Hunting!

Translated by