How to trim a surface intersecting with another

Hi all, I have two surfaces Z1 and Z2 (a surface and an extruded line) that intersect with each other, in point format with two different grids. What I want to accomplish is to trim the left part of the Z1 surface after its point of intrersection with Z2 as shown in the example below, so that I can obtain the trimmed surface (lets call it Z1t ) in its new point format, as a series of three matrices.
Below is the example code the creates the above (without the trimming part obviously). The reason that I am struggling to accomplish that, is because the surfaces that I am given do not share the same grid, as I also demonstrate in my code below. So I do not have the exact points where they intersect. Moreover, when I attempt to place those surfaces on the same grid using griddata , I am getting a matrix full of NaN.
clear ; clc
n = 20 ;
x1 = linspace(1,10,n) ;
y1 = linspace(-25,25,n) ;
x2 = linspace(1,10,n) ;
y2 = linspace(-10,10,n) ;
[X1, Y1] = meshgrid(x1, y1) ; % Grid 1
[X2, Y2] = meshgrid(x2, y2) ; % Grid 2
Z1 = sin(X1) + cos(Y1) ; % Surface
Z2 = X2.*sin(X2) ; % Line (extruded for plotting)
z2 = x2.*sin(x2) ; % Line (not extruded)
% Match grid surface to line
[~, ~, Z2new] = griddata(x2, y2, z2, x1, y1') ;
figure
surf(X1,Y1,Z1)
hold on
surf(X2,Z2,Y2)
P.S. I have seen other posts with similar subjects, however they don't address this problem exactly. There is this post which seems to offer a valuable hint, however I don't get how to implement the method. Also, there is this post that straight-up doesn't work for me when dealing with different grid sizes. Finally, this post seems to get the closes, however I can't obtain the new plane in point format.
Thanks for your help in advance

 Accepted Answer

Try this—
n = 50 ;
x1 = linspace(1,10,n) ;
y1 = linspace(-25,25,n) ;
x2 = linspace(1,10,n) ;
y2 = linspace(-10,10,n) ;
[X1, Y1] = meshgrid(x1, y1) ; % Grid 1
[X2, Y2] = meshgrid(x2, y2) ; % Grid 2
Z1 = sin(X1) + cos(Y1) ; % Surface
Z2 = X2.*sin(X2) ; % Line (extruded for plotting)
z2 = x2.*sin(x2) ; % Line (not extruded)
% Match grid surface to line
[~, ~, Z2new] = griddata(x2, y2, z2, x1, y1') ;
Lv = nan(size(X1)); % Create 'NaN' Matrix
Lv(Y1<=Z2) = 1; % Set Selected Elements TO 'true'
figure
surf(X1.*Lv,Y1.*Lv,Z1.*Lv) % Multiply Matrices By 'Lv' To Approximate Desired Result
hold on
surf(X2,Z2,Y2)
hold off
xlabel('X')
ylabel('Y')
view(-37.5,30)
grid on
figure
surf(X1.*Lv,Y1.*Lv,Z1.*Lv)
hold on
surf(X2,Z2,Y2)
hold off
xlabel('X')
ylabel('Y')
view(150.5,60)
grid on
title('Rotated To See Result')
.

4 Comments

Thanks for your answer it definitely works. In my particular example however the same logic doesn't seem to work and I am really struggling to understand why. I know you have answered my question so I have accepted, but I would appreciate it if you could take a look at the below, it should be something really simple I am missing...
Essentially I want to trim the lower part of the yellow surface from the blue surface, but there are still some points that haven't been removed:
clear ; clc
load('data')
Lv = nan(size(X1)) ;
idx = Z1 > Z2 ;
Lv(idx) = 1 ;
figure
surf(X1, Y1.*Lv, Z1)
hold on
surf(X2, Y2, Z2, 'FaceColor', 'b')
zlim([0 45])
ylim([1 5])
xlim([4000 12000])
The solution is to interpolate to a higher resolution. (It took a bit of time to get all that working correctly.)
The code initially interpolates to a higher resolution (defined by ‘n’), and plots it. The problem is that at a higher resolution, the grid lines on the surfaces (actually, ‘Edges’) are then so dense that they obscure the surfaces, so the code turns them off. The problem is that they are necessary in order to see the details of the surfaces. The solution to that problem is first to eliminate them, then add selected ones back (governed by ‘nstep’) in a second surf call, this time setting the faces to be completely transparent ('FaceAlpha',0).
LD = load('data.mat');
X1 = LD.X1;
X2 = LD.X2;
Y1 = LD.Y1;
Y2 = LD.Y2;
Z1 = LD.Z1;
Z2 = LD.Z2;
n = 150; % Interpolate To Higher REsolution
x1v = linspace(min(X1(:)), max(X1(:)), n);
y1v = linspace(min(Y1(:)), max(Y1(:)), n);
[X1n,Y1n] = meshgrid(x1v,y1v);
Z1n = griddata(X1(:),Y1(:),Z1(:),X1n,Y1n);
x2v = linspace(min(X2(:)), max(X2(:)), n);
y2v = linspace(min(Y2(:)), max(Y2(:)), n);
[X2n,Y2n] = meshgrid(x2v,y2v);
Z2n = griddata(X2(:),Y2(:),Z2(:),X2n,Y2n);
Lvn = nan(size(X1n)) ;
idx = Z1n > Z2n ;
Lvn(idx) = 1 ;
n_step = 3;
figure
surf(X1n, Y1n.*Lvn, Z1n, 'EdgeColor','none') % Plot Higher Resolution
hold on
surf(X1n(1:n_step:end,1:n_step:end), Y1n(1:n_step:end,1:n_step:end).*Lvn(1:n_step:end,1:n_step:end), Z1n(1:n_step:end,1:n_step:end), 'FaceAlpha',0, 'EdgeColor',[1 1 1]*0.3) % Add Back Selected Grid Lines
surf(X2n, Y2n, Z2n, 'FaceColor', 'b', 'EdgeColor','none')
surf(X2n(1:n_step:end,1:n_step:end), Y2n(1:n_step:end,1:n_step:end), Z2n(1:n_step:end,1:n_step:end), 'FaceAlpha',0, 'EdgeColor',[1 1 1]*0.3) % Add Back Selected Grid Lines
zlim([0 45])
ylim([1 5])
xlim([4000 12000])
Experiment with this to get different results.
The onlline application will not allow me to run this code here since I cannot load ‘data.mat’, so I did everything offline.
.
Yep, that seems to work. So essentially you have re-gridded the data from the beginning down to a common grid. Thanks for taking the time, greatly appreciated.
As always, my pleasure!

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!