matlab - 一个关于在MATLAB中绘制曲面图的问题
问题描述
我写了一个用于拓扑优化的matlab代码。在曲面图中显示结果的代码是:(一个非常简单的示例)
XYZG=[2.5 0 0;2.5 0 2.5;2.5 0 5;0 -2.5 0;0 -2.5 2.5;0 -2.5 5;-2.5 0 0;-2.5 0 2.5;-2.5 0 5];
ELNOD=[1 4 5 2;2 5 6 3;4 7 8 5;5 8 9 6];
nelement=4;
Dens=[0 1 1 0];
for element=1:nelement
for i=1:4
X(i)=XYZG(ELNOD(element,i),1);
Y(i)=XYZG(ELNOD(element,i),2);
Z(i)=XYZG(ELNOD(element,i),3);
end
XX=[X(1) X(2);X(4) X(3)];
YY=[Y(1) Y(2);Y(4) Y(3)];
ZZ=[Z(1) Z(2);Z(4) Z(3)];
tick=-Dens(element)*[1 1;1 1];
figure(1)
hold on
surf(XX,YY,ZZ,tick);
colormap gray;
end
这段代码太慢了。例如,如果我有 10,000 个元素,则绘制绘图需要很长时间。因此,我将不胜感激有关如何加快速度的任何帮助。
解决方案
1] 小改进:
您作为示例提供的代码可以简化以避免临时分配。考虑以下:
%% Sample data
XYZG=[2.5 0 0;2.5 0 2.5;2.5 0 5;0 -2.5 0;0 -2.5 2.5;0 -2.5 5;-2.5 0 0;-2.5 0 2.5;-2.5 0 5];
ELNOD=[1 4 5 2;2 5 6 3;4 7 8 5;5 8 9 6];
nelement=4;
Dens=[0 1 1 0];
%% pre-initialisation just to set the size (size=[2,2])
XX = zeros(2) ;
YY = XX ;
ZZ = XX ;
figure(1)
hold on
colormap gray;
for element=1:nelement
% Base vector combining (unused now)
% idx=1:4;
% X = XYZG( ELNOD(element,idx),1 ).';
% Y = XYZG( ELNOD(element,idx),2 ).';
% Z = XYZG( ELNOD(element,idx),3 ).';
% The block above is commented because we do not need these intermediate
% vectors to build the base matrices XX, YY and ZZ.
% This can be done directly using linear indexing:
idxOrder = [1 4 2 3] ;
XX(1:4) = XYZG( ELNOD(element,idxOrder) , 1 ) ;
YY(1:4) = XYZG( ELNOD(element,idxOrder) , 2 ) ;
ZZ(1:4) = XYZG( ELNOD(element,idxOrder) , 3 ) ;
tick=-Dens(element)*[1 1;1 1];
surf(XX,YY,ZZ,tick) ;
end
这应该稍微快一点。由于避免了一些临时数组。我们现在更直接地构建每个补丁坐标。此外,只需要使用一次的函数调用也已从循环中取出(如果您的循环花费的时间太长,通常要寻找的东西)。
现在这无论如何都不会令人满意。结构中的真正瓶颈与其说是每次循环迭代中的计算/索引,不如说是系统必须维护的图形句柄数量不断增加。循环的每次迭代都会创建一个surface
对象。这些对象需要内存来保持它们的坐标,还要保持大量的内部属性。一旦你将这些对象相乘,你的系统就会开始变慢。一些系统甚至可能无法在同一个图形上创建 10,000 个表面图形对象,如果可以的话,这将是一个缓慢的痛苦(你知道这些情况,你点击屏幕并等待大约 25 秒以注意到任何反应...... )。
2]主要改进:
限制图形对象数量的一种方法是组合所有这些坐标以创建单个图形对象。当然,我们必须根据您的规则为每张脸着色。
幸运的是,我注意到您的基本坐标实际上组织得很好,可以直接作为patch
Matlab 中的 a 注入。所以不需要解复用/重新复用输入和输出的数据,我们可以直接创建和着色全局补丁:
% create a Black and White colormap
cmap = [1 1 1;
0 0 0] ;
figure
% generate a patch with all the 'faces','vertices' and 'color' data :-)
hp = patch('Faces',ELNOD, 'Vertices',XYZG, 'FaceVertexCData',Dens(:) ) ;
% last refinement to have the same appearance than in former code
shading flat
colormap(cmap)
hp.EdgeColor = 'k' ; % <= this needs to be executed AFTER "shading flat"
瞧!不需要任何循环或任何计算。您已经拥有了所有需要的数据;-)
我鼓励您阅读 的文档patch
,尤其是使用该属性的方式FaceVertexCData
推荐阅读
- html - 尽管有内容,但反应 div 标签高度为零,
- mongodb - JMeter 使用 Java BeanShell 将文档保存到 MongoDb:JSR223 脚本采样器中的问题
- c# - 参数如何在 C# 的引擎盖下工作
- matlab - 如何解决具有多个边界条件的 BVP?
- javascript - 在 OnDisconnected 方法之前执行脚本
- c# - 创建复杂的数据结构
- amazon-web-services - 如何配置 AWS Amplify 的 Storage.put 以使用传输加速的 s3 存储桶域?
- r - 不断收到错误:期望单个值:总结中的 [extent=2]
- c++ - 如何使递归河内塔与 OpenMP 并行工作
- c++ - 我试图编写代码来计算文件行中的字符数,但 ifstream 对象没有从文件中获取该行