MATLAB中的三维曲面细分

MATLAB中的三维曲面细分,matlab,plot,3d,matlab-figure,surface,Matlab,Plot,3d,Matlab Figure,Surface,我正在使用MATLAB创建一些图表来解释我的研究,我被困在下面的问题上。我已经创建了一个绕x轴旋转的半椭球体,但我想展示一下椭球体内部的一些结构,它将绕x轴和y轴旋转。这大致如下图所示,其中我将椭球体细分为四个部分(使用我糟糕的绘画技巧) 如何使用绕x轴和y轴旋转不同的平面将椭球细分为多个部分?我可以创建椭球体和相交平面,但从那里我不知道如何分割椭球体并更改面颜色 我已经在下面包含了一些基本代码来开始工作。我原以为我可以像把椭球切成两半那样屏蔽部分椭球坐标,但这不起作用。我猜我需要制作某种网格

我正在使用MATLAB创建一些图表来解释我的研究,我被困在下面的问题上。我已经创建了一个绕x轴旋转的半椭球体,但我想展示一下椭球体内部的一些结构,它将绕x轴和y轴旋转。这大致如下图所示,其中我将椭球体细分为四个部分(使用我糟糕的绘画技巧)

如何使用绕x轴和y轴旋转不同的平面将椭球细分为多个部分?我可以创建椭球体和相交平面,但从那里我不知道如何分割椭球体并更改面颜色

我已经在下面包含了一些基本代码来开始工作。我原以为我可以像把椭球切成两半那样屏蔽部分椭球坐标,但这不起作用。我猜我需要制作某种网格,但我不知道如何从相交曲面和椭球体组合网格

figure
x   = 0;    y   = 0;    z   = 0;
tl  = 10;   tw  = 4;   td  = 2;

% Create ellipsoid
[ex,ey,ez]  = ellipsoid(x, y, z, tl, tw, td,40);
ex          = ex(1:ceil(length(ez)/2),:);   % Remove top half 
ey          = ey(1:ceil(length(ez)/2),:);   % of ellipsoid
ez          = ez(1:ceil(length(ez)/2),:);

% Make some planes
[ySL,zSL] = meshgrid([-10:10],[-2:0.2:2]);
xSL1 = zeros(size(ySL, 1)); % Generate z data
hSL1 = surf(xSL1,ySL,zSL);

hold on
[ySL,zSL] = meshgrid([-10:10],[-3:0.2:1]);
xSL2 = ones(size(ySL, 1)); % Generate z data
hSL2 = surf(xSL2,ySL,zSL);

% rotate(hSL,[1 0 0],5);
rotate([hSL1 hSL2],[0 1 0],-70);

hSurf1  = surf(ex,ey,ez);
set([hSurf1 hSL1 hSL2],'facecolor','blue','facealpha',.2,...
    'edgecolor','none')

% Plot settings
daspect([1 1 0.3]);
hold off
view(-10,6)

非常感谢您的帮助,

这是一个有趣的问题。因此,这里有一个解决方案,用于1)在椭圆内绘制三维点,以两个平面为边界,2)获取这些点以形成平滑的面片表示

我的基本想法是构建一个覆盖整个X-Y-Z感兴趣空间的网格(根据需要密集)。然后我要做的是以参数形式定义这两个变量
ax+by+cz+d=0
。这些是要在其中绘制数据的平面。使用平面的法向量,结合每个平面上的一个点的信息,我可以使用点积推断X-Y-Z网格中的每个点是在平面之上还是之下:如果点积小于零,点在平面之上,如果大于零,点在平面之上

然后使用,我找到网格上的哪些点满足以下条件:1)在平面1上方,2)在平面2下方,3)在椭球体内部,以及--4)在
Z=0
下方

最后,我绘制了椭球体和平面,以及满足上述标准的点

在本例中,我定义了两个平面,但我想您可以对任意数量的平面执行此操作。代码是快速和肮脏的,但希望能给你一个前进的道路

% Define the ellipse
x   = 0;    y   = 0;    z   = 0;
tl  = 10;   tw  = 4;   td  = 2;

% Create ellipsoid
[ex,ey,ez]  = ellipsoid(x, y, z, tl, tw, td,40);
ex          = ex(1:ceil(length(ez)/2),:);   % Remove top half 
ey          = ey(1:ceil(length(ez)/2),:);   % of ellipsoid
ez          = ez(1:ceil(length(ez)/2),:);


% Define a 3D grid over area of interest
xx = linspace(min(ex(:)),max(ex(:)),50);
yy = linspace(min(ey(:)),max(ey(:)),50);
zz = linspace(min(ez(:)),max(ez(:)),50);
[X, Y, Z] = meshgrid(xx, yy, zz);
V = [X(:) Y(:) Z(:)]; % rearrange

% Define two planes (ax + bx + cz + d = 0)
a = [0; 0];
b = [-1; 1];
c = [-1; 1];
d = [-1; -1];
% Normal vectors of the planes
n = [a b c];
n(1,:) = n(1,:) / norm(n(1,:));
n(2,:) = n(2,:) / norm(n(2,:));

% Find a point (0,0,z) on each plane
zp = [zeros(2) (d- a * 0 - b * 0)./c];

% Define the area of interest.
% Dot product to test if grid points are below or above the planes
% We want: above plane 1, below plane 2.
V1 = sum(bsxfun(@times, bsxfun(@minus, V, -zp(1,:)), n(1,:)),2);
V2 = sum(bsxfun(@times, bsxfun(@minus, V, -zp(2,:)), n(2,:)),2);
between_planes = (V1 < 0) & (V2 < 0);
% ...and the points have to be inside the ellipsoid
in_ellipse = ((X(:) - x)/tl).^2 + ((Y(:)-y)/tw).^2 + ((Z(:)-z)/td).^2 < 1;
% Final AOI
aoi = between_planes & in_ellipse;

% Add this if you want to also have only values with Z < 0
aoi = aoi & (V(:,3) < 0);

figure;
surf(ex, ey, ez, 'facecolor','blue','facealpha',.2,...
    'edgecolor','none')
…为了查看它的效果,让我们将前面定义的平面添加到可视化中。这可能是你最终想要摆脱的东西

% Draw the planes
[X,Y] = meshgrid(xx,yy);
Z = cell(2,1);
clr = {'r', 'g'};
for k = 1:2
    Z{k} = (a(k) * X + b(k) * Y + d(k))/ (-c(k));
    hs(k) = surf(xx, yy, Z{k},'facecolor',clr{k}, 'facealpha',.2, 'edgecolor','none');
    drawnow;
end
view([-115 10])
legend(hs, 'Plane 1 (above)', 'Plane 2 (below');
最后,如果我们想展示一些平滑的数据,我们可以用它来从这些数据点中提取多面体。我们只需使用
plot
即可将多面体可视化为一个对象。最后,我们可以为面片中的每个顶点指定我们想要的任何颜色,通过设置
'Facecolor'
属性设置对可视化颜色的平滑更改,并通过将
'EdgeColor'
设置为
'none'
删除讨厌的顶点边:

% Moving on to smooth representation...
shp = alphaShape(V(aoi,1), V(aoi, 2), V(aoi, 3),1);
hs = plot(shp);
% Create a colormap to use for the patch (color of each vertex)
cmap = jet(size(hs.Vertices,1));
set(hs, 'FaceVertexCData', cmap);
set(hs, 'FaceColor', 'interp'); % smooth interp coloring
set(hs, 'EdgeColor', 'none'); % Remove ugly edges
就这样。剩下的就是将顶点颜色值替换为适合数据的值。此外,如果不希望这些数据点显示在面片的显示中,请记住跳过前面的
plot3
部分

下面的最终结果示例也显示了这两个平面。

在您的代码中,
exR
eyR
ezR
未定义。定位正确-在我的代码中,我旋转椭球体(因此是“R”),但这与我的问题无关。我已经改变了,好的。所以用
ex
来代替
exR
就可以了,等等?编辑:好的,看起来是这样。是的,我已经编辑了原始问题中的代码。我对自己旋转形状/曲面的能力感到满意。另一个问题:最终要在椭圆中绘制的数据是什么格式?只是
(x,y,z)
点或某种网格?这是一个很好的答案,但理想情况下,我会有某种光滑的表面(如我原来帖子中的椭球)而不是网格。这可能吗?我认为目前的答案将有助于我解决一个相关的问题,当我有足够的声誉时,我会投票支持它…@driftingtides谢谢!事实证明,使用这些点提取多面体非常简单,我们可以为其设置一个漂亮的平滑面颜色。我更新了答案。太好了。这回答了我的问题。由于使用常规栅格/网格,渲染的最终多面体与原始椭球体不完全匹配。通过使网格更精细,我可以在某种程度上缓解这种情况。最终,我希望使用某种参数化曲面(例如,但我可能需要稍微提高我的几何技能)。
% Moving on to smooth representation...
shp = alphaShape(V(aoi,1), V(aoi, 2), V(aoi, 3),1);
hs = plot(shp);
% Create a colormap to use for the patch (color of each vertex)
cmap = jet(size(hs.Vertices,1));
set(hs, 'FaceVertexCData', cmap);
set(hs, 'FaceColor', 'interp'); % smooth interp coloring
set(hs, 'EdgeColor', 'none'); % Remove ugly edges