Как нарисовать взвешенный выпуклый корпус в Matlab - PullRequest
4 голосов
/ 21 октября 2019

Предположим, у меня есть массив Matlab PE размером Ex1. Элементы PE находятся между 0 и 1, и они в сумме составляют один.

Возьмите другой массив PEY размера ExY. Элементы PEY равны единице или нулю. Более того, для каждого ряда существует хотя бы один. Y=3.

Например,

clear
E=4;
Y=3;
PE=[1/2; 1/6; 1/6; 1/6];
PEY=[1 0 0; 0 1 1; 1 1 1; 0 1 1]; 

Теперь рассмотрим симплекс с вершинами (1,0,0), (0,1,0) и (0,0,1)

patch([0 0 1],[0 1 0],[1 0 0],[0.8 0.8 0.8]);
axis equal 
axis([0 1 0 1 0 1])
view(120,30)

Я хочу нарисоватьвыпуклое подмножество A такого симплекса. A построен следующим образом.

ШАГ 1: Мы создаем Ex1 массив ячеек PEY_expanded такой, что для каждой e -ой строки PEY, которая имеет более 1, мы пишемсложите все допустимые 1xY векторы, содержащие только 1, и сложите их в PEY_expanded{e}.

PEY_expanded=cell(E,1);

for e=1:E
    if isequal(PEY(e,:),[1 1 1])
       PEY_expanded{e}=[1 0 0; 0 1 0; 0 0 1]; 
    elseif isequal(PEY(e,:),[1 1 0])
       PEY_expanded{e}=[1 0 0; 0 1 0];
    elseif isequal(PEY(e,:),[1 0 1])
       PEY_expanded{e}=[1 0 0; 0 0 1];
    elseif isequal(PEY(e,:),[0 1 1])
       PEY_expanded{e}=[0 1 0; 0 0 1];
    else
       PEY_expanded{e}=PEY(e,:);
    end
end

ШАГ 2: Возьмите декартово произведение PEY_expanded{1} x PEY_expanded{2} x ... PEY_expanded{E} и получите PEY_cartesian.

Примечание: приведенный ниже код относится только к E=4 и не является общим

size_PEY_expanded=zeros(E,1);
for e=1:E
size_PEY_expanded(e)=size(PEY_expanded{e},1);
end

[a,b,c,d]=ndgrid(1: size_PEY_expanded(1),1: size_PEY_expanded(2),...
                 1: size_PEY_expanded(3), 1: size_PEY_expanded(4));

PEY_Cartesian= [PEY_expanded{1}(a,:),PEY_expanded{2}(b,:),...
                PEY_expanded{3}(c,:), PEY_expanded{4}(d,:)];

PEY_Cartesian_rearranged=cell(prod(size_PEY_expanded),1);
for i=1:prod(size_PEY_expanded)
    PEY_Cartesian_rearranged{i}=[PEY_Cartesian(i,1:3); PEY_Cartesian(i,4:6);...
                                 PEY_Cartesian(i,7:9);  PEY_Cartesian(i,10:end)];
end

PEY_Cartesian=PEY_Cartesian_rearranged;

ШАГ 3: Для каждой возможной ячейки PEY_Cartesian, для y=1,...,Y, вес PEY_Cartesian{i}(e,y) на PE(e), а затем сумма по e.

PY=zeros(prod(size_PEY_expanded),Y);
for i=1:prod(size_PEY_expanded)
    for y=1:Y
        temp=0;
        for e=1:E
               temp=temp+PE(e)*PEY_Cartesian{i}(e,y);
        end
        PY(i,y)=temp;
    end
end

ШАГ 4 : Нарисуйте область A, которая является выпуклой оболочкой из строк PY (черная область на рисунке)

%Need https://fr.mathworks.com/matlabcentral/fileexchange/37004-suite-of-functions-to-perform-uniform-sampling-of-a-sphere
close all
patch([0 0 1],[0 1 0],[1 0 0],[0.8 0.8 0.8]);
axis equal 
axis([0 1 0 1 0 1])
view(120,30)
hold on
T = delaunayTriangulation(PY);
K = convexHull(T);
patch('Faces',K,'Vertices',T.Points,'FaceColor','k','edgecolor','k');
hold on

ВОПРОС:

Приведенный выше алгоритм невозможен для больших E. В моем случае у меня есть E=216, например. В частности, шаг 2 неосуществим. Не могли бы вы предложить более простой способ продолжить? Учитывая, что A является выпуклой областью, возможно, есть какой-то ярлык, который я не вижу.

...