在MATLAB

时间:2015-11-26 12:21:52

标签: matlab plot 3d matlab-figure surface

我正在使用MATLAB创建一些图表来解释我的研究,并坚持以下问题。我已经创建了一个围绕x轴旋转的半椭圆体,但我想展示椭圆体内的一些内部结构,它将围绕x轴和y轴旋转。这大致如下图所示,我将椭圆体细分为四个部分(我的画笔技能不好)。

enter image description here

如何使用围绕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 个答案:

答案 0 :(得分:1)

这是一个有趣的问题。因此,这里有一个解决方案:1)绘制椭圆内部的三维点,由两个平面限定,以及2)将这些点绘制成平滑的补丁表示。

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

使用logical indexing然后我找到网格上的哪些点满足条件1)在平面1,2下方的平面2,以及3)椭球内部和 - 可选 - 4){{1 }}

最后,我绘制了椭圆体和平面,以及符合上述标准的点。

在这种情况下,我定义了两个平面,但我想你可以为任意数量的平面做这个。代码快速而且肮脏,但希望能为您提供前进的方法!

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')

...只是为了看它的工作原理,让我们将之前定义的平面添加到可视化中。这可能是你最终想要摆脱的。

hold on;
plot3(V(aoi,1), V(aoi, 2), V(aoi, 3), 'r.')

好吧,最后,如果我们想要显示一些平滑的数据,我们可以使用alphaShape从我们拥有的那些数据点中提取多面体。我们可以使用% 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'); 将多面体可视化为patch对象。最后,我们可以为贴片中的每个顶点指定我们想要的任何颜色,通过设置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 部分。

下面的示例结果,也显示了两个平面。 End result.