Delaunay triangulation
This program demostrates iterative construction of delaunay triangulation and voronoi tesselation.
It draws a random set of points in an image and then delaunay triangulates them.
Sources:
function delaunay2_demo() % prepare delay = 0.25; active_facet_color = [0, 0, 255]; delaunay_color = [255, 255, 255]; rect = [0, 0, 600, 600]; window = figure('KeyPressFcn',@(o,e)setappdata(o,'flag',true)); setappdata(window, 'flag',false); disp('This program builds the traingulation interactively,'); disp('you may stop this process by hitting any key.'); % initialize subdiv = cv.Subdiv2D(rect); img = zeros([rect(3:4) 3], 'uint8'); h = imshow(img); title('Delaunay Triangulation') % for i=1:100 % generate random 2D point fp = [randi([5 rect(3)-5]), randi([5 rect(4)-5])]; % locate and draw triangle containing point img = locate_point(img, subdiv, fp, active_facet_color); set(h, 'CData',img), xlabel(num2str(i)) pause(delay) flag = getappdata(window, 'flag'); if isempty(flag) || flag, break; end % add point and draw the new triangulation subdiv.insert(fp); img(:) = 0; img = draw_subdiv(img, subdiv, delaunay_color); set(h, 'CData',img) pause(delay) flag = getappdata(window, 'flag'); if isempty(flag) || flag, break; end end fprintf('\nGenerated %d random points.\n', i); % draw the Voronoi diagram img(:) = 0; img = paint_voronoi(img, subdiv); %img = draw_subdiv(img, subdiv, delaunay_color); figure, imshow(img), title('Voronoi diagram') end function img = locate_point(img, subdiv, fp, active_color) [~, e0, vertex] = subdiv.locate(fp); if e0 > 0 e = e0; while true [ee1, org] = subdiv.edgeOrg(e); [ee2, dst] = subdiv.edgeDst(e); if ee1 > 0 && ee2 > 0 img = cv.line(img, org, dst, ... 'Color',active_color, 'Thickness',3, 'LineType','AA'); end e = subdiv.getEdge(e, 'NextAroundLeft'); if e == e0 break; end end end % draw_subdiv_point img = cv.circle(img, fp, 5, ... 'Color',fliplr(active_color), 'Thickness','Filled', 'LineType',8); end function img = draw_subdiv(img, subdiv, delaunay_color) opts = {'Color',delaunay_color, 'Thickness',1, 'LineType','AA'}; if true triangleList = subdiv.getTriangleList(); % faster implementation triangleList = cellfun(@(t) num2cell(reshape(round(t),2,3),1), ... triangleList, 'UniformOutput',false); img = cv.polylines(img, triangleList, 'Closed',true, opts{:}); % slower %{ for i=1:numel(triangleList) t = round(triangleList{i}); img = cv.line(img, t(1:2), t(3:4), opts{:}); img = cv.line(img, t(3:4), t(5:6), opts{:}); img = cv.line(img, t(5:6), t(1:2), opts{:}); end %} else edgeList = subdiv.getEdgeList(); % faster implementation edgeList = cellfun(@(e) num2cell(reshape(round(e),2,2),1), ... edgeList, 'UniformOutput',false); img = cv.polylines(img, edgeList, 'Closed',true, opts{:}); % slower %{ for i=1:numel(edgeList) e = round(edgeList{i}); img = cv.line(img, e(1:2), e(3:4), opts{:}); end %} end end function img = paint_voronoi(img, subdiv) % get Voronoi faces and corresponding centers [facets, centers] = subdiv.getVoronoiFacetList([]); for i=1:numel(facets) % draw face as a colored closed patch color = randi([0 255], [1 3]); img = cv.fillConvexPoly(img, facets{i}, 'Color',color, 'LineType',8); % draw the center as a dot img = cv.circle(img, centers{i}, 3, ... 'Thickness','Filled', 'LineType','AA'); end % draw the borders img = cv.polylines(img, facets, 'Closed',true, ... 'Thickness',1, 'LineType','AA'); end
This program builds the traingulation interactively, you may stop this process by hitting any key. Generated 6 random points.