Info

Cette question est clôturée. Rouvrir pour modifier ou répondre.

How do I calculate the distance between 3D coordinate points using cell array?

1 vue (au cours des 30 derniers jours)
lil brain
lil brain le 7 Fév 2022
Clôturé : lil brain le 13 Fév 2022
Hi,
I am trying to find the distances between pairs of 3D coordinate points. I have a cell array as my data set. Inside each cell there are 6 columns of cells with 2 rows. Each column of cells represents a dimension (XYZ) and each row of cells represents a participant. The following columns are important here:
position_a = [x1 y1 z1];
position_b = [x2 y2 z2];
x1 = windowed_data{1,1}(:,1);
y1 = windowed_data{1,1}(:,2);
z1 = windowed_data{1,1}(:,3);
x2 = windowed_data{1,1}(:,4);
y2 = windowed_data{1,1}(:,5);
z2 = windowed_data{1,1}(:,6);
I am looking to create a new cell array in the same form of the original windowed_data with all the distances between all the elements in x1,y1,z1 and x2,y,z2 using the following formula:
distance_data = sqrt(sum((position_a - position_b) .^ 2))
As an example, the output I am aiming for should look like this:
distance_sample = distance_data{1,1}{1,1}(:,1);
=
distance_data = sqrt(sum((position_a_sample - position_b_sample) .^ 2))
position_a:sample = [x1_sample y1_sample z1_sample];
position_b_sample = [x2_sample y2_sample z2_sample];
x1_sample = windowed_data{1,1}{1,1}(:,1);
y1_sample = windowed_data{1, 1}{1, 2}(:,1);
z1_sample = windowed_data{1, 1}{1, 3}(:,1);
x2_sample = windowed_data{1,1}{1,4}(:,1);
y2_sample = windowed_data{1, 1}{1, 5}(:,1);
z2_sample = windowed_data{1, 1}{1, 6}(:,1);
How would I go about doing this for the entire data set (each row of cells)? Apologies in advance if some parts of this question are redundant or incorrect. I hope its clear what I am trying to do.
Thanks for the support!
  2 commentaires
Johan
Johan le 7 Fév 2022
Hello,
you can use the cellfun function which applies a defined function on each cell of a cell array:
% make some data
concatenated_cell = cellfun(@(x) [rand(2,6)],cell(2,6),'UniformOutput',false)
concatenated_cell = 2×6 cell array
{2×6 double} {2×6 double} {2×6 double} {2×6 double} {2×6 double} {2×6 double} {2×6 double} {2×6 double} {2×6 double} {2×6 double} {2×6 double} {2×6 double}
% compute the norm for each cell and force output as cell with,'UniformOutput',false
distance_as_cell = cellfun(@(x) norm(x(1,1:3)-x(1,4:6)),concatenated_cell,'UniformOutput',false)
distance_as_cell = 2×6 cell array
{[0.3311]} {[0.9969]} {[0.8290]} {[0.4653]} {[1.0050]} {[0.3253]} {[0.3750]} {[0.1665]} {[0.6797]} {[0.5667]} {[0.5708]} {[0.9158]}
To do that to cells of a cell array you can concatenate the cellfun function:
Data(1)= {concatenated_cell};
Data(2)= {cellfun(@(x) [rand(2,6)],cell(2,6),'UniformOutput',false)};
Distance_in_Cells = cellfun(@(y) cellfun(@(x) norm(x(1,1:3)-x(1,4:6)),y,'UniformOutput',false), Data,'UniformOutput',false)
Distance_in_Cells = 1×2 cell array
{2×6 cell} {2×6 cell}
Distance_in_Cells{1}
ans = 2×6 cell array
{[0.3311]} {[0.9969]} {[0.8290]} {[0.4653]} {[1.0050]} {[0.3253]} {[0.3750]} {[0.1665]} {[0.6797]} {[0.5667]} {[0.5708]} {[0.9158]}
I used the norm function here, it does the same as sqrt(sum(x-y)^2) as far as I know.
Hope this helps.
lil brain
lil brain le 8 Fév 2022
@Johan Pelloux-Prayer Thank you for your answer!
I had a look at the code and tried it out but I think that you might have misunderstood the question or perhaps I didnt phase it correctly. I changed the data set slightly to test your code on it.
>> windowed_data_test{1, 1}
ans =
2×6 cell array
{10×1 double} {10×1 double} {10×1 double} {10×1 double} { 10×1 double} { 10×1 double}
{10×2 double} {10×2 double} {10×2 double} {10×2 double} {512×2 double} {512×43 double}
When I run your code on windowed_data_test it gives me an error.
Index in position 2 exceeds array bounds (must not exceed 1).
Error in @(x)norm(x(1,1:3)-x(1,4:6))
Error in @(y)cellfun(@(x)norm(x(1,1:3)-x(1,4:6)),y,'UniformOutput',false)
It seems to me as though your code creates a distance for each cell. Perhaps this example makes it more clear what I am trying to achieve:
position_1a_test = [x1a y1a z1a];
position_2b_test = [x2b y2b z2b];
x1a = windowed_data{1,1}{1,1}(1,1)
y1a = windowed_data{1, 1}{1, 2}(1,1)
z1a = windowed_data{1, 1}{1, 3}(1,1)
x2b = windowed_data{1,1}{1,4}(1,1)
y2b = windowed_data{1, 1}{1, 5}(1,1)
z2b = windowed_data{1, 1}{1, 6}(1,1)
... and if we continue in this way:
position_1n_test = [x1n y1n z1n];
position_2n_test = [x2n y2n z2n];
x1n = windowed_data{1,1}{2,1}(4,2)
y1n = windowed_data{1, 1}{2, 2}(4,2)
z1n = windowed_data{1, 1}{2, 3}(4,2)
x2n = windowed_data{1,1}{2,4}(4,2)
y2n = windowed_data{1, 1}{2, 5}(4,2)
z2n = windowed_data{1, 1}{2, 6}(4,2)
In my full data set all the rows have different sized cells meaning that I need to cycle through all the elements in all the columns in the cells. I hope this makes it a bit more clear.
I am very thankful for the help!

Réponses (0)

Community Treasure Hunt

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

Start Hunting!

Translated by