This is the code I ended up using (a combination of the suggestions):
%// Fill in area between low frequency bands
f1=f(r1)'; %'// <-- this prevents string markdown
Zm1=Zm(r1);
Z1=Z(r1);
mask = Zm1 <= Z1;
fx = [f1(mask), fliplr(f1(mask))];
fy = [Zm1(mask),fliplr(Z1(mask))];
hold on
fill_color = [.040 .040 1];
fh = fill(fx,fy,fill_color);
hold off
%fh.EdgeColor = 'none';
delete(fh)
hold on
output = [];
%// Calculate t in range [0 1]
calct = @(n) (n(3,1)-n(2,1))/(n(3,1)-n(2,1)-n(3,2)+n(2,2));
%// Generate interpolated X and Y values
interp = @(t,n) n(:,1) + t*(n(:,2) - n(:,1));
for i=1:length(f1)
%// If y2 is below y1, then we don't need to add this point.
if Z1(i) <= Zm1(i)
%// But first, if that wasn't true for the previous point, then add the
%// crossing.
if i>1 && Z1(i-1) > Zm1(i-1)
neighborhood = [f1(i-1), f1(i); Zm1(i-1), Zm1(i); Z1(i-1), Z1(i)];
t = calct(neighborhood);
output(:,end+1) = interp(t,neighborhood);
end
else
%// Otherwise y2 is above y1, and we do need to add this point. But first
%// ...
%// ... if that wasn't true for the previous point, then add the
%// crossing.
if i>1 && Z1(i-1) <= Zm1(i-1)
neighborhood = [f1(i-1), f1(i); Zm1(i-1), Zm1(i); Z1(i-1), Z1(i)];
t = calct(neighborhood);
output(:,end+1) = interp(t,neighborhood);
end
%// add this point.
output(:,end+1) = [f1(i); Z1(i); Zm1(i)];
end
end
xout = output(1,:);
topout = output(2,:);
botout = output(3,:);
fh = fill([xout fliplr(xout)],[botout fliplr(topout)],fill_color);
fh.EdgeColor = 'none';
uistack(fh,'bottom')
hold off
I repeated this for high frequencies.
The resulting plot: