MATLAB - 3D 曲面图 [英] MATLAB - 3D surface plot
问题描述
我在 3D 空间中有 20 个数据点.在这里你可以看到它们的绘制:
清除所有关闭所有液晶显示器数据 = [97.4993 104.3297 0.7500 196.7021100.0000 105.0000 0.7500 290.9164100.0000 107.5000 0.7500 142.162696.2569 106.4992 0.7500 143.360597.5028 104.3317 1.0000 197.1111100.0000 105.0000 1.0000 290.4210100.0000 107.5000 1.0000 144.015596.2530 106.4969 1.0000 144.096998.7055 104.8295 0.7500 239.7734100.0000 106.2500 0.7500 214.655798.0627 107.2455 0.7500 145.415496.8781 105.4144 0.7500 161.700097.5010 104.3307 0.8750 196.8880100.0000 105.0000 0.8750 290.6686100.0000 107.5000 0.8750 141.500896.2549 106.4980 0.8750 144.025398.7075 104.8300 1.0000 239.3455100.0000 106.2500 1.0000 215.210498.0605 107.2449 1.0000 144.965396.8779 105.4143 1.0000 161.4253];x = 数据(:,1);% x 坐标y = 数据(:,2);% y 坐标z = 数据(:,3);% z 坐标sigma = 数据(:,4);% 应力值在该点对于 ii = 1:length(x)plot3(x(ii,1),y(ii,1),z(ii,1),'r*')坚持,稍等网格开启text(x(ii,1),y(ii,1),z(ii,1),[' ' num2str(ii) ' '...num2str(sigma(ii))],'HorizontalAlignment','left','FontSize',12);结尾
该数据代表一个 HEX20 元素 (FEM) 及其 20 个节点.每个节点旁边都写有其应力值 (sigma).节点编号遵循标准程序:
我想绘制该元素的表面,如图所示.然后(如果可能)我希望根据节点的应力值(颜色映射)对表面进行着色.最终结果应该是这样的:
这是构建补丁的另一种方法.您指定一个包含点(顶点)的结构,然后是面(它们包括哪些点),然后是颜色向量(您的 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);坚持,稍等hp = patch(fv,'CDataMapping','scaled','EdgeColor',[.7 .7 .7],'FaceColor','interp','FaceAlpha',1)hp3 = plot3(x,y,z,'ok','Markersize',6,'MarkerFaceColor','r')对于 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');结尾视图(-27,26)轴相等轴关闭南彩条
将产生:
这比要求 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 分的人脸,它会以同样的方式工作.
I have 20 data points in 3D space. Here you can see them plotted:
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
This data represents one HEX20 element (FEM) and its 20 nodes. Each node has its Stress value (sigma) written next to it. The numbering of the nodes follows the standard procedure:
I would like to plot the surfaces of that element like it is shown in the picture. Then (if possible) I would like the surfaces to be coloured based on the stress value of the nodes (colour mapping). The end result should be something like this:
Here's another way of building patches. You specify a structure with the points (vertices), then the faces (which points do they include), then a vector of color (your sigma
values), then you send the lot to the patch function which will take care of the rest.
Then you finalise the details (transparency, edge color, plot your points and text etc ...)
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
Will produces:
Edit:
It is slightly more tedious than asking convhull
to find the envelope, but it has the merit of respecting the actual shape of your element (not closing the inward small volume near nodes 9 & 17).
To avoid the graphic rendering glitch when the patch faces are not perfectly planar, you can define the faces so they will all be perfectly planar. It means defining more faces (we have to split all of them in 2), but it goes round the glitch and now all your faces are visible. So if you want to go that way, just replace the face definition above by:
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 ] ;
There are more than one way to define the faces, just notice that each line of the faces
vector, is a succession of point defining an area (the face will close itself down, no need to repeat the first point in the end to close the surface).
We went from faces with 8 points to faces with 5 points ... if you want to play/refine your model, you could try using 3 points faces, it would work the same way.
这篇关于MATLAB - 3D 曲面图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!