MATLAB - 3D曲面图

时间:2015-05-06 13:36:36

标签: matlab plot 3d surface

我在3D空间中有20个数据点。在这里你可以看到它们的绘制:

clear all
close all
clc

Data = [97.4993     104.3297    0.7500  196.7021
        100.0000    105.0000    0.7500  290.9164
        100.0000    107.5000    0.7500  142.1626
        96.2569     106.4992    0.7500  143.3605
        97.5028     104.3317    1.0000  197.1111
        100.0000    105.0000    1.0000  290.4210
        100.0000    107.5000    1.0000  144.0155
        96.2530     106.4969    1.0000  144.0969
        98.7055     104.8295    0.7500  239.7734
        100.0000    106.2500    0.7500  214.6557
        98.0627     107.2455    0.7500  145.4154
        96.8781     105.4144    0.7500  161.7000
        97.5010     104.3307    0.8750  196.8880
        100.0000    105.0000    0.8750  290.6686
        100.0000    107.5000    0.8750  141.5008
        96.2549     106.4980    0.8750  144.0253
        98.7075     104.8300    1.0000  239.3455
        100.0000    106.2500    1.0000  215.2104
        98.0605     107.2449    1.0000  144.9653
        96.8779     105.4143    1.0000  161.4253];

x = Data(:,1); % x coordinates 
y = Data(:,2); % y coordinates 
z = Data(:,3); % z coordinates 
sigma = Data(:,4); % stress value at that point

for ii = 1:length(x)

    plot3(x(ii,1),y(ii,1),z(ii,1),'r*')
    hold on
    grid on
    text(x(ii,1),y(ii,1),z(ii,1),['   ' num2str(ii) '   '...
        num2str(sigma(ii))],'HorizontalAlignment','left','FontSize',12); 

end

此数据代表一个HEX20元素(FEM)及其20个节点。每个节点都在其旁边写入应力值(sigma)。节点的编号遵循标准过程:

HEX20 Element

我想绘制该元素的表面,如图所示。然后(如果可能的话)我希望根据节点的应力值(颜色映射)对表面进行着色。最终结果应该是这样的:

enter image description here

2 个答案:

答案 0 :(得分:2)

您基本上想要将数据转换为网格对象。 x,y,z坐标构成Vertices或点,您可以通过加入Faces定义Vertices,然后可以设置单个点或Vertex到具有特定的颜色值(在您的情况下是应力值)。要使用verticesfaces绘制网格,您可以使用patch方法。

这里的难点是你有顶点,但不是面孔。一种快速尝试的方法是convhull,它返回一组点的凸包(想想收缩包装点以得到表面)。

首先:

patch('Vertices',[x y z],'Faces',convhull(x,y,z),'FaceVertexCData',sigma,'FaceColor','interp');

看看它是怎么回事,如果它不是你想要的那么你就可以改变faces。在上面的代码行中,faces = convhull(x,y,z)。您可能已经知道哪些顶点构成了您的面孔,例如Face1可以是第2点,第14点和第9点 - faces(1,:) = [2,14,9]

此外,如果您想要由四个点而不是三角形组成的面,那么您的面部阵列将只是N-by-4而不是N-by-3。

您提供的代码和上面的patch代码的快速示例结果:

Quick example from the code you gave

http://uk.mathworks.com/help/matlab/visualize/multifaceted-patches.html http://uk.mathworks.com/help/matlab/ref/convhull.html

答案 1 :(得分:2)

这是构建补丁的另一种方法。你指定一个结构,包括点(顶点),然后是面(它们包含哪些点),然后是颜色矢量(你的sigma值),然后你将批次发送到补丁函数,这将照顾其余的。

然后你最终确定细节(透明度,边缘颜色,绘制你的点和文字等......)

fv.vertices = Data(:,1:3);
fv.faces = [...
    1  9 2 10 3 11 4 12 ;
    1  9 2 14 6 17 5 13 ;
    5 17 6 18 7 19 8 20 ;
    2 10 3 15 7 18 6 14 ;
    3 11 4 16 8 19 7 15 ;
    4 12 1 13 5 20 8 16 ...
    ] ;
fv.facevertexcdata = Data(:,4);

hold on
hp  = patch(fv,'CDataMapping','scaled','EdgeColor',[.7 .7 .7],'FaceColor','interp','FaceAlpha',1)    
hp3 = plot3(x,y,z,'ok','Markersize',6,'MarkerFaceColor','r')

for ii = 1:length(x)
    text(x(ii,1),y(ii,1),z(ii,1),{sprintf('   #%d - \\sigma:%4.1f',ii,sigma(ii))},...
        'HorizontalAlignment','left','FontSize',8,'FontWeight','bold'); 
end
view(-27,26)
axis equal
axis off
colorbar south

将产生:

fem

编辑: 要求convhull找到信封稍微繁琐一些,但它的优点是要尊重元素的实际形状(不要关闭节点9和17附近的向内小体积)。

为了避免补丁面不是完美平面时的图形渲染毛刺,您可以定义面,使它们都完全平面。这意味着定义更多的面孔(我们必须将它们全部分成2个面),但它绕过毛刺,现在所有的面都可见了。 因此,如果你想这样做,只需将上面的面部定义替换为:

fv.faces = [...
     1  9 11 4 12 ;
     9  2 10 3 11 ;
     1  9 17 5 13 ;
     9  2 14 6 17 ;
     2 10 18 6 14 ;
    10  3 15 7 18 ;
     3 11 19 7 15 ;
    11  4 16 8 19 ;
     4 12 20 8 16 ;
    12  1 13 5 20 ;
     5 17 19 8 20 ;
    17  6 18 7 19 ] ;

定义面的方法不止一种,只需注意faces向量的每一行,是一个定义一个区域的连续点(面将自行关闭,无需重复第一个点到最后关闭表面)。 我们从8点的面孔到5点的面孔...如果你想玩/改进你的模型,你可以尝试使用3点面,它会以同样的方式工作。