2016-12-02 3 views
4

У меня есть два набора точек и plot их в синих звездах и красных точках. Затем I plot Диаграмма Вороного для обоих наборов с функцией voronoi(X,Y). Я хочу указать цвет каждой ячейки, зависит от того, какой набор принадлежит сайту. Я почти сделал это один за счет использования patch функции таким образом:Цвет неограниченных клеток диаграммы ворона в MATLAB

 [v,c]=voronoin(D); 
    for p=1:TheNumberOfSets 
     r=rand()/2+0.5; % random gray color 
     col=[r r r]; 
     for s=1:PointsInSet(p) 
      l=l+1; 
      patch(v(c{l},1),v(c{l},2),col); % color 
      axis([0 10 0 10]); 
     end 
    end 

Где D это координаты точек множеств, TheNumberOfSets показывают, сколько наборов мы имеем (в этой конкретной части мы имеем только 2 набора), col укажите случайный серый цвет, PointsInSet укажите, сколько точек у нас есть в каждом наборе, а l используется для перечисления ячеек диаграммы Вороного.

и это результат: enter image description here

теперь моя проблема (как вы можете видеть!) О неограниченных клетках. Этот код просто меняет цвет ограниченных ячеек, и я хочу раскрасить неограниченные ячейки с цветом их указанного набора в диапазоне окна оси (т. Е. Поле, которое вы видите на изображении).

Любое предложение?

+1

Не могли бы вы добавить информацию об образце из 'TheNumberOfSets',' 'PointsInSet', L',' V', 'c',' col', и все, что я, возможно, пропустили ? См. Файл справки на [mcve] (http://stackoverflow.com/help/mcve) для получения дополнительной информации о том, как сделать правильный пример вашей проблемы. –

+0

Я добавил дополнительную информацию. @FranzHahn –

+0

Как насчет 'l'? –

ответ

1

Ваш пример действительно создает объекты для неограниченных ячеек, но поскольку они содержат вершины с Inf значениями, представляющими неограниченные ребра, они не отображаются. Вам нужно заменить эти вершины на конечные, чтобы завершить патчи.

Вершины, сгенерированные voronoi для рисования границ неограниченной ячейки, полезны для этой цели. Вы можете получить их при составлении диаграммы Вороной:

h = voronoi(D); 
v1 = shiftdim(reshape([h(2).XData;h(2).YData],2,3,[]),2); % Arranged one edge per row, one vertex per slice in the third dimension 

неограниченных ребра построены в прошлом, так что вы можете изолировать их путем подсчета неограниченных клеток в c:

nUnbounded = sum(cellfun(@(ic)ismember(1,ic),c)); 
v1Unbounded = v1(end-(nUnbounded-1):end,:,:); 

Первые перечисленные вершины этих ребер - конечная вершина ячейки. Они не всегда точно совпадают координаты, возвращаемые voronoin из-за ошибки с плавающей точкой, поэтому определить, какие пронумерованные вершины они соответствуют путем нахождения минимального расстояния от парного pdist2:

[~,iBounded] = min(pdist2(v,v1Unbounded(:,:,1))); % Index of the bounded vertex 
vUnbounded = v1Unbounded(:,:,2); % Displayed coordinate of the unbounded end of the cell edge 

Чтобы заменить в этих координатах вы можете затем заменить patch(v(c{l},1),v(c{l},2),col); следующим:

cPatch = c{l}; % List of vertex indices 
vPatch = v(cPatch,:); % Vertex coordinates which may contain Inf 
idx = find(cPatch==1); % Check if cell has unbounded edges 
if idx 
    cPatch = circshift(cPatch,-idx); % Move the 1 to the end of the list of vertex indices 
    vPatch = [vPatch(1:idx-1,:) 
       vUnbounded(iBounded == cPatch(end-1),:) 
       vUnbounded(iBounded == cPatch(1),:) 
       vPatch(idx+1:end,:)]; % Replace Inf values at idx with coordinates from the unbounded edges that meet the two adjacent finite vertices 
end 
patch(vPatch(:,1),vPatch(:,2),col); 
+0

Большое вам спасибо за этот замечательный ответ (через месяц вы первый). У меня просто одна проблема для запуска вашего кода. После 'h = voronoi (D);', 'h' имеет только один столбец, а не две строки диаграммы, поэтому я получаю ошибку: ** Ссылка на неправильную ссылку на индексную строку ** для' h (2) .XData'. Конечно, я использую MATLAB R2014a и видел ** Примечание. Поведение h = voronoi (..) изменилось. Новое поведение возвращает вектор двух графических строк; один из которых представляет точки, а другой представляет края Вороного ** в [mathworks] (https://www.mathworks.com/help/matlab/ref/voronoi.html). У вас есть идея @Will? Еще раз спасибо –

+0

О, дорогая! Похоже, что в R2014a координаты линии все еще доступны через дескрипторы, которые все еще возвращаются в 'h', но порядок ручек и структура данных линии может быть не таким, как описано выше, и вы не можете использовать точечную нотацию, как в' .XData' для доступа к нему. Он явно не документирован вообще, поэтому потребуется небольшое исследование, чтобы определить, где найти правильные значения, чтобы заменить их на вход 'patch', как указано выше. Если я правильно помню, вы должны иметь доступ ко всем данным линии, используя 'get (h, {'XData', 'YData'})'. – Will

+0

Еще раз спасибо @. Я попробовал 'get (h, {'XData', 'YData'})' и получил класс ячейки 14x2 для 7 пунктов; Который, как это: первая строка: '[1x7 двойной] [1x7 двойной]' вторая строка: '[1х2 двойной] [1x2 двойной]' третья строка: '[1х2 двойной] [1x2 двойной]' ... Я попытаюсь понять это и поместить это для своего кода, и я знаю, что ваш ответ верен. С уважением. –

Смежные вопросы