Subtracting XYZ coordinates defined by matrices

14 visualizzazioni (ultimi 30 giorni)
I have two matrices, A (96100x3) and B(16416x3). I need to subtract the XYZ coordinates defined by the columns of B from those of A. But as they are of different resolutions, the difference or setxor is still giving sort of union of these two matrices.
Is there any way I can subtract the region bounded by B from A?
TIA
  6 Commenti
Image Analyst
Image Analyst il 23 Gen 2021
Isaac, so you have this:
A = [6 1 2; 7 2 7; 1 4 7; 7 7 4; 5 7 6]
B = [6.1 1.2 2.3; 1.2 4.1 7.4]
C = [7 2 7; 7 7 4; 5 7 6]
A =
6 1 2
7 2 7
1 4 7
7 7 4
5 7 6
B =
6.1 1.2 2.3
1.2 4.1 7.4
C =
7 2 7
7 7 4
5 7 6
Can you explain how you get each of the 3 rows of C? Why would you want 3 rows from C when A had 5 rows and B had 2 rows? C does not even have any fractional parts - it's all integers even though B is not integers. Explain your thought process.
Isaac John
Isaac John il 23 Gen 2021
Thank you for your patience.
The idea is two subtract the point cloud defined by B from A. Normally, I would have gone for C = setxor(A,B,'rows'), if the rows in B are exactly matching A. Had B been [6 1 2; 1 4 7] instead of the being [6.1 1.2 2.3; 1.2 4.1 7.4], C = C = setxor(A,B,'rows') would have yielded C = [7 2 7; 7 7 4; 5 7 6], which is basically the point cloud B subtracted from A.
But the case that I have is, the given rows of B are not exactly matching with A and hence, setxor(A,B,'rows') does not yield the desired answer.
For instance let A correspond to the point cloud corresponding to a sphere and B correspond to a smaller, concentric sphere. The result (equivalent to setxor) that I am seeking is a hollow sphere, that is a resultant of subracting the smaller sphere from the larger sphere.

Accedi per commentare.

Risposta accettata

Adam Danz
Adam Danz il 23 Gen 2021
Modificato: Adam Danz il 23 Gen 2021
I think what you're asking is how to remove rows of A that are nearly equal to rows of B. Removal is different from subtraction and setxor does the former, not the latter.
The question is, what do you define as "near"?
I used pdist2() to compute the pairwise distances between all points in A and B and there is no obvious cluster of distances around 0 (note, pdist2 will be slow due to large variable sizes!).
% Read-in the data
A = readmatrix('A.xlsx');
B = readmatrix('B.xlsx');
% Compute pair-wise distance.
% This will probably take several seconds or more! size: 96100 x 16416
pd = pdist2(A,B);
% Plot distribution of pair-wise distances
figure()
histogram(pd(:), 20)
xlabel('paired distance')
ylabel('count')
title('All points')
% Show +/- 1 std
mu = mean(pd(:));
sd = std(pd(:));
xline(mu-sd,'k-')
xline(mu+sd,'k-')
When we look at distances around 0:.2, there is still no clear cluster that would support an objective definition of "near".
figure()
histogram(pd(pd<.2))
xlabel('paired distance')
ylabel('count')
title('Points at distances less than 0.2')
The minimum distance is
min(pd(:))
% ans =
% 0.000316512059369112
If there were a clear definition of "near" you could use that as a threshold to detect and remove "near" coordinates from the pd pair-wise distance matrix. But that isn't clear from the data.
If, on the other hand, you're looking for coordinates that are nearly 1 unit apart in distanced, then the data above do suggest a clear, more-objective way to detect and eliminate paired coordinates at nearly 1-unit distance, though you'll still need to subjectively select a threshold distance from 1.
For example, any pairwise distance within 0.05 of 1 identifies a row of A to be removed.
rmIdx = abs(pd-1) < .05;
A(any(rmIdx,2)) = [];
  4 Commenti
Adam Danz
Adam Danz il 24 Gen 2021
Modificato: Adam Danz il 24 Gen 2021
The idea is to minimized any subjective decisions by using the data to set thresholds. This requires exploration of the data.
Here's another visualization of your data zoomed into the section of overlap between A (blue o) and B (red x). This view is from the "top" where each marker is actually a column of markers in 3D.
A = readmatrix('A.xlsx');
B = readmatrix('B.xlsx');
plot3(A(:,1), A(:,2), A(:,3), 'o')
hold on
plot3(B(:,1), B(:,2),B(:,3), 'rx')
view(2)
axis equal
xlim([-.05 .25])
ylim([.33 .88])
This is only a small portion of your entire dataset.
And with this view we also see that the mean distance of 1 between points in A and B is irrelevant because you're only concerned with the portion of overlap and those distances a lot closer than 1.
What you need to do is repeat the pdist2 calculations but only for the section of overlap. That will greatly reduce the number of data points and will prevent the maximum array size error you got.
  1. Get the min & max values for X and Y coordinates in B
  2. Isolate the section of A based on those ranges (add a little space)
  3. Repeat the pdist2 calculations I showed you and plot the distribution of distances. The distribution should be much closer to 0.
Isaac John
Isaac John il 24 Gen 2021
Great job Adam, much appreciated.

Accedi per commentare.

Più risposte (1)

Image Analyst
Image Analyst il 24 Gen 2021
"For instance let A correspond to the point cloud corresponding to a sphere and B correspond to a smaller, concentric sphere. The result (equivalent to setxor) that I am seeking is a hollow sphere, that is a resultant of subracting the smaller sphere from the larger sphere."
Sounds like you want convhulln(). Use it on one cloud and then test all the points of one to see if the point is inside the convex hull of the other.

Prodotti

Community Treasure Hunt

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

Start Hunting!

Translated by