Plotting level sets of a function on a triangulated surface.

조회 수: 8 (최근 30일)
Roy Goodman
Roy Goodman 2025년 7월 2일
댓글: Mathieu NOE 2025년 8월 25일
I want to plot the level sets of one function g(x,y,z) as curves on an isosurface f(x,y,z)=c. The following code comes close, but I need help getting over the finish line.
[x,y,z] = meshgrid(-1:.025:1);
f = x.^2 +y.^2 + z.^2;
g = x.^2 - y.^2;
c = 0.8
[faces,verts,colors] = isosurface(x,y,z,f,c,g);
patch('Vertices',verts,'Faces',faces,'FaceVertexCData',colors,...
'FaceColor','interp','EdgeColor','none')
view(3)
axis equal
colormap(turbo(10))
In this example code, we can see the level sets as the boundaries between the colored regions, but what I really want is
  • Curves on a solid-colored sphere
  • The ability to choose which values of g(x,y,z) get plotted
  • The ability to choose line styles, colors, and thicknesses
  댓글 수: 1
Roy Goodman
Roy Goodman 2025년 7월 3일
A comment on my original question. The issue boils down to computing the intersection of implicitly defined surfaces. The blog "Mike on MATLAB Graphics" discussed this issue in a post in 2015.
User TimeCoder turned the ideas discussed in this post were turned into a File Exchange submission Intersection of 2 surfaces.
Jaroslaw Tuszynski submitted another solution to the same problem to File Exchange a few years earlier.
Between these two packages and Mathieu's accepted answer, I should be able to solve my problem.
Still, If I could extract the borders between the different colors in the colored image above, I would be done. I wonder how to do this..

댓글을 달려면 로그인하십시오.

채택된 답변

Mathieu NOE
Mathieu NOE 2025년 7월 2일
hello
this is maybe not yet the perfect solution, but ....you can get your curves as 3D points , isolated in separate clusters (thank you dbscan : DBSCAN Clustering Algorithm - File Exchange - MATLAB Central )
NB that I had to modify a bit the PlotClusterinResult.m file (attached)
now remains to make it a bit prettier...
here we have slected level = 0.2 and we get two clusters of scattered data (that need now to be transformed into a smooth closed curve)
[x,y,z] = meshgrid(-1:.025:1);
f = x.^2 +y.^2 + z.^2;
g = x.^2 - y.^2;
c = 0.8;
[faces,verts,colors] = isosurface(x,y,z,f,c,g);
figure,
patch('Vertices',verts,'Faces',faces,'FaceVertexCData',colors,...
'FaceColor','interp','EdgeColor','none')
view(3)
axis equal
hold on
x = verts(:,1);
y = verts(:,2);
z = verts(:,3);
colormap(turbo(10));
level = 0.2; % select level
tol = 0.01;
% extract points that are within tolerance
ind = abs(colors - level)<tol;
xs = x(ind);
ys = y(ind);
zs = z(ind);
%% Run DBSCAN Clustering Algorithm
epsilon=0.2;
MinPts=10;
X = [xs ys zs];
IDX=DBSCAN(X,epsilon,MinPts);
%% Plot Results
PlotClusterinResult(X, IDX);
title(['DBSCAN Clustering (\epsilon = ' num2str(epsilon) ', MinPts = ' num2str(MinPts) ')']);
colorbar('vert')
  댓글 수: 5
Roy Goodman
Roy Goodman 2025년 7월 3일
That looks great. Thanks. Of course I uploaded a minimal example. If I have any trouble with the real problem, I will let you know.
Mathieu NOE
Mathieu NOE 2025년 7월 3일
hello again
tx for accepting my answer
BTW, I found a faster alternative to the euclidean function I sent you before
with euclidean_distance.m it goes at least 10 times faster, can be valuable for large data sets !
DBSCAN code must be updated : (really minor update)
% compute distance
% D = pdist2(X,X); % method 1 (original code)
% D = euclidean(X,X); % alternative code (ok but slow)
D = euclidean_distance(X,X); % fastest alternative code

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Roy Goodman
Roy Goodman 2025년 7월 30일
Here is the solution I eventually came up with. It uses the intersection of two surfaces code that I reference in my previous comment.
function contoursOfGonF(f,g,xyzbox,gLevels)
% Plot the surface f(x,y,z)=0 and plot level contours of g(x,y,z) on that
% surface
%
% Input parameters
% f - the function to be plotted as a surface
% g - the function whose contours will be laid on top
% xyzbox - the plotting region [xmin xmax ymin ymax zmin zmax]
% gLevels - if a vector, a set of g-values to plot
% - if a scalar, the number of evenly spaced g-values to plot
set(gcf,'Visible','off')
[h1, hel1] = imsurf(f, xyzbox);
xyz=h1.Vertices;
x=xyz(:,1);y=xyz(:,2);z=xyz(:,3);
gg=g(x,y,z);
gMin = min(gg); gMax=max(gg);
if isscalar(gLevels)
nG=gLevels;
gLevels=linspace(gMin,gMax,nG+2); gLevels=gLevels(2:end-1);
else
nG = length(gLevels);
if all(gLevels>gMax) || all(gLevels<gMin)
error('no g levels on the plotted surface')
end
end
x=cell(nG,1);y=cell(nG,1);z=cell(nG,1);
hold on;axis equal;
for k = 1:nG
gf = @(x,y,z)g(x,y,z)-gLevels(k);
[~, hel2] = imsurf(gf, xyzbox);
h = intercurve(hel1, hel2);
x{k}=h.XData;y{k}=h.YData;z{k}=h.ZData;
end
clf
[h1,~]=imsurf(f,xyzbox);
hold on
for k=1:nG
plot3(x{k},y{k},z{k},'k','LineWidth',2)
end
set(gcf,'Visible','on')
axis equal
set(h1,'facecolor',.8*[1 1 1])
set(h1,'FaceAlpha',.9)
camlight;
An example call
contoursOfGonF(@(x,y,z)x.^2+y.^2+z.^2-1,@(x,y,z)x.^2-y.^2,1.1*[-1 1 -1 1 -1 1],.4*(-2:2));
returns the following image

카테고리

Help CenterFile Exchange에서 Lighting, Transparency, and Shading에 대해 자세히 알아보기

제품


릴리스

R2025a

Community Treasure Hunt

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

Start Hunting!

Translated by