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. Так что нет необходимости демультиплексировать / повторно мультиплексировать данные в и из, мы можем напрямую создать и раскрасить глобальный патч:
% 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