How to change the C values that matches a 3 coordinates position condition?
조회 수: 1 (최근 30일)
이전 댓글 표시
%Here you can daownload variables.mat
%https://drive.google.com/file/d/1EgdpHSz_aXM0JG2lJL6QrahYavIPhTRR/view?usp=sharing
load('variables.mat')
figure();hold on
scatter3(xq(:),yq(:),zq(:),1,'filled','k');
scatter3(xq(:),yq(:),zq(:),1,cq(:),'filled')
scatter3(top(:,1),top(:,2),top(:,3),10,'filled','r')
scatter3(bot(:,1),bot(:,2),bot(:,3),10,'filled','r')
This code creates the following plot
I would like to set all the points cq(:) as NaN located in xq(:),yq(:),zq(:) that are above and below top and bot (desired top and bottom boundaries). I was trying with ismmber to set with indeces but xq,yq,zq positions, does not match with top and bot positions. Any advice?
댓글 수: 0
채택된 답변
Wan Ji
2021년 8월 17일
편집: Wan Ji
2021년 8월 17일
Hi, friend! Just use scatteredInterpolant
% Here is how I process
Ftop = scatteredInterpolant(top(:,1), top(:,2), top(:,3), 'linear');
Fbot = scatteredInterpolant(bot(:,1), bot(:,2), bot(:,3), 'linear');
p_nan = zq>Ftop(xq,yq)|zq<Fbot(xq,yq);
% set all the points cq(:) as NaN located in xq(:),yq(:),zq(:) that are above and below top and bot
cq(p_nan) = NaN;
% Here is your code
figure();hold on
%scatter3(xq(:),yq(:),zq(:),1,'filled','k');
scatter3(xq(:),yq(:),zq(:),1,cq(:),'filled')
scatter3(top(:,1),top(:,2),top(:,3),10,'filled','r')
scatter3(bot(:,1),bot(:,2),bot(:,3),10,'filled','r')
I cannot download your data but I have a small test, see following figures
추가 답변 (1개)
Dave B
2021년 8월 17일
Similar to https://www.mathworks.com/matlabcentral/answers/897257-set-points-that-matches-with-a-vector-as-nan we can solve this with interpolation, but here we have to use interp2 instead of interp1.
This is challenging because it's a large dataset, and because the shapes of your top and bot arrays are a little awkward. Before I show the interp2 solution, I thought it might be helpful to show a loop version which is slower and not matrix oriented, but maybe helps think about what math needs to be done. This assumes that both top and bot's x,y correspond exactly to the xq and yq values, which they seem to do in this dataset.
for i = 1:height(xq)
for j = 1:width(xq)
thistop = top(top(:,1) == xq(i,j) & top(:,2) == yq(i,j),3);
thisbot = bot(bot(:,1) == xq(i,j) & bot(:,2) == yq(i,j),3);
ind = zq(i,j,:) > thistop | zq(i,j,:) < thisbot;
cq(i,j,squeeze(ind))=nan;
end
end
For the interp2 version, we really want a matrix of z values, with x's and y's that look like what meshgrid produces. I'm not sure of a simple way to get that in a generic way based on your matrices, but it's apparent that (for top at least) the x,y values are reshaped versions of such a matrix. (This also appears to be the case for bot, except that the first row is a duplicate).
xi_top=reshape(top(:,1),80,80)';
yi_top=reshape(top(:,2),80,80)';
zi_top=reshape(top(:,3),80,80)';
this makes a matrix for x,y,z where for any row/column the x,y co-ordinates are xi(row,col),yi(row,col) and the z co-ordinate of the top is zi(row,col).
Now we're ready to interpolate:
top_i=interp2(xi_top,yi_top,zi_top,xq,yq,'nearest');
The result top_i is the top that corresponds to each xq,yq. We'll do the same for bot:
xi_bot=reshape(bot(2:end,1),80,80)';
yi_bot=reshape(bot(2:end,2),80,80)';
zi_bot=reshape(bot(2:end,3),80,80)';
bot_i=interp2(xi_bot,yi_bot,zi_bot,xq,yq,'nearest');
Now we have something really useful: bot_i and top_i are co-ordinates of the top and bottom in a shape that exactly matches zq and cq. So marking NaN is as easy as:
cq(zq<bot_i | zq>top_i)=nan;
댓글 수: 2
Dave B
2021년 8월 17일
FWIW the scatteredInterpolant approach also works well for these problems. I thought about that because it's so much easier to work with the shapes that scatteredInterpolant wants, but fundamentally this is a gridded interpolation problem so it felt like I should have a gridded interpolation solution. In the end, it probably doesn't really matter!
참고 항목
카테고리
Help Center 및 File Exchange에서 Matrix Indexing에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!