Help using contourc without meshable x-y data

1 view (last 30 days)
Eugenio Grabovic on 2 Oct 2019
I have a surface of which i would like to compute a section with the z = a plane using contourc function.
if we try to plot the surface:
surf(pinionSurf.X, pinionSurf.Y, pinionSurf.Z)
axis equal
size(pinionSurf.X)
we can notice this surface is not built from meshed [X,Y] grid.
if i use the contour function i have no problems getting the contourMatrix:
a = 3;
contourMat = contour(pinionSurf.X, pinionSurf.Y, pinionSurf.Z, [a, a]);
But for performance reasons, and since i need just the matrix without the plotting, i would like to use the contourc function to perform the "low-level" computation.
The problem is contourc function accepts only x and y array values which are going to be meshed into a grid internally (the helper indeed says x and y length have to be respectively the same size as the rows and columns of Z matrix).
My question is: is there a way to manipulate my data in order to use it inside contourc function and have the same results the normal contour function gives?
I attached my surface example into a struct.
thank you

Stephen Cobeldick on 2 Oct 2019
Edited: Stephen Cobeldick on 2 Oct 2019
Interestingly contour does not directly call contourc anywhere, instead it passes its input arguments to a contourgroup constructor, and all the magic happens inside that...
This opens the possibility of one undocumented solution: call the contourgroup constructor directly with "visible" "'off":
h = specgraph.contourgroup('Visible','off', 'LevelList',3, 'XData',pinionSurf.X, 'YData',pinionSurf.Y, 'ZData',pinionSurf.Z, 'RefreshMode','auto');
M = get(h, 'ContourMatrix')
delete(h)
This gives exactly the same output as your contour call, just without the visible graphics (and hence faster). I realize that this still technically involves graphics...
Another undocumented option is to call contours directly:
M = contours(pinionSurf.X, pinionSurf.Y, pinionSurf.Z, [a,a]);
This also returns exactly the same matrix. Note that the contourgroup constructor actually calls contours, which in turn calls contourc with just the Z matrix, and then post-processes the output matrix before returning it as an output argument. Of course I cannot advise you to reverse-engineer MATLAB code... but calling contourc with just the Z matrix is trivial... sadly the post processing is not so trivial, but it is worth taking a look at.

Eugenio Grabovic on 2 Oct 2019
excellent, exactly what i was looking for, didn't even know the existence of contours function. I see that it calls contourc at some point and processes the output back. I might check how the post processing algorithm works in the future if i need more performance boost, but as for now the performance is already great. Thank you !
Stephen Cobeldick on 2 Oct 2019
@Eugenio Grabovic : see the attached code.
Eugenio Grabovic on 2 Oct 2019
Even better, thank you again ! Amazing how quickly you managed to realize which part of the code wasn't useful for my specific case.