【问题标题】:MATLAB - 3D surface plotMATLAB - 3D 曲面图
【发布时间】:2015-05-07 19:19:08
【问题描述】:

我在 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)。节点编号遵循标准程序:

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

【问题讨论】:

    标签: matlab plot 3d surface


    【解决方案1】:

    这是构建补丁的另一种方法。您指定一个包含点(顶点)的结构,然后是面(它们包括哪些点),然后是一个颜色向量(您的 sigma 值),然后您将批次发送到 patch 函数,该函数将处理休息。

    然后确定细节(透明度、边缘颜色、绘制点和文本等...)

    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
    

    将产生:

    编辑: 这比要求 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 分的脸,它的工作方式是一样的。

    【讨论】:

    • @Hoki 感谢您的代码。这绝对是一个进步!我接受你的答案是正确的!
    • @ViharChervenkov。谢谢。我稍微修改了代码以更多地考虑尺寸比(axis equal 将使 x、y、z 尺寸具有相同的比例,因此您的元素将用正确的相对尺寸表示,如您的示例所示)
    • @Hoki 这更好。我看到的唯一问题是背面(节点 3 11 4 16 8 19 7 15)未连接到节点 11 和 19。任何想法如何解决?
    • @ViharChervenkov。你是什​​么意思 ?这些节点连接到我模型上的面部:i.imgur.com/8KYQjDo.png(与view(166,32)
    • @Hoki 它们连接到顶面和底面。但是当你从侧面看时(从节点 7 和 3 到节点 8 和 4),你会看到面部只连接到节点 7、3、8 和 4,而没有连接到节点 11 和 19。如果你告诉我怎么做,我可以把视图号码发给你。谢谢!
    【解决方案2】:

    您本质上想将数据转换为网格对象。 x,y,z 坐标组成Vertices 或点,您可以通过连接Vertices 来定义Faces,然后可以设置单个点或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×4 而不是 N×3。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多