I cannot find a way to plot some dots on lower and upper ridge of my surface. I wrote this code for surface:
%initialize parameters
x = linspace(-2,2,100);
y = linspace(-2,2,80);
fxy = abs(log(x'.*y));
% it looks like this
figure(1), clf
surf(x,y,fxy')
shading interp
axis square, rotate3d on
xlabel('X'), ylabel('y'), zlabel('f(x,y)')
And for finding lower ridge I wrote something like the following:
% find min
minval = min(min(fxy));
[xi,yi] = find( minval == fxy);
idx = sub2ind(size(fxy),xi,yi);
% plot the minimum as a red ball
hold on
plot3(x(xi),y(yi),fxy(idx)','ro', 'MarkerFaceColor','r','MarkerSize',12 )
Then for lower bound (lower ridge) I set a threshold 0.1 and then:
% finding lower ridge : points below a threshold of .01
[xi,yi] = find( fxy < minval+.01);
% to get the values, convert from matrix indices to linear indices
idx = sub2ind(size(fxy),xi,yi);
% plot the close-to minimum points
plot3(x(xi),y(yi),fxy(idx)','ro','markerfacecolor','r','markersize',12)
Now for maximum I did this:
% finding maximum
maxval = max(max(fxy));
[xi,yi] = find( maxval == fxy);
% plot the maximum as a red ball
plot3(x(xi),y(yi),fxy(xi,yi)','ro', 'MarkerFaceColor','r','MarkerSize',12 )
now how can I find upper ridge? I set threshold 5 for upper, and the result was like this:
% finding upper ridge : points below a threshold of 5
[xi,yi] = find( maxval- fxy <5);
% to get the values, convert from matrix indices to linear indices
idx = sub2ind(size(fxy),xi,yi);
% plot the close-to minimum points
plot3(x(xi),y(yi),fxy(idx)','ro','markerfacecolor','r','markersize',12)
which would be is the the best threshold to obtain only upper ridge? is there any other way to plot dots only on upper edge?
For the top ridges, in a general case I would follow Adriaan comment and look at the derivative (you can use the fucntion gradient
for that).
However in your case there is another approach, made possible by the fact that:
X
slice of your surface fxy
, the ridge y
coordinate will coincide with the max value of this X
slice.Y
slice of your surface fxy
, the ridge x
coordinate will coincide with the max value of this Y
slice.Armed with this observation, the max
function is all you need:
% Find maximum Z value and index for
[zxmax,idxzx] = max(fxy) ; % All X slices (columns)
[zymax,idxzy] = max(fxy,[],2) ; % All Y slices (rows)
xr = x(idxzx) ; % get the actual X coordinates from the column indices
yr = y(idxzy) ; % get the actual Y coordinates from the row indices
% Display
hold on
plot3(xr,y,zxmax,'r','LineWidth',4)
plot3(x,yr,zxmax,'b','LineWidth',4)
% Or if you want them dotted
% plot3(xr,y,zxmax,'or')
% plot3(x,yr,zymax,'ob')
This plotted on top of your initial surface display will render: