Effacer les filtres
Effacer les filtres

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?

5 vues (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)

Cette question est clôturée.

Community Treasure Hunt

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

Start Hunting!

Translated by