Create polygons from circles x, y and radii

101 views (last 30 days)

I have 11k circles with the x/y coordinates and radii, but I want to patch them all with specific colours from the 11000-by-3 RGB colour matrix. While I use patch for my other problems, it only accepts polygon input. So I want to create polygons (with many points/faces so they still look like round) from these circles. I think it can be done with `polyshape`, but I'm not really sure (maybe use sin/cos) on how to to create polygon coordinates from the x/y/radii of the circles.

EDIT

To give you an impression on what I'm working with, I plotted the circles. The circles are derived from delaunay triangles.

Accepted Answer

Bruno Luong
Bruno Luong on 21 Oct 2018
Edited: Bruno Luong on 21 Oct 2018
Your input
xc = 1;
yc = 2;
r = 3;
n = 100;
Generate polyshape n-points of a circle with center (xc,yc) radius r
theta = (0:n-1)*(2*pi/n)
x = xc + r*cos(theta);
y = yc + r*sin(theta);
P = polyshape(x,y)
P =
polyshape with properties:
Vertices: [100×2 double]
NumRegions: 1
NumHoles: 0
Plot it
plot(P)
axis equal
  8 Comments
YT
YT on 21 Oct 2018
Okay so after I ran your example except for the colouring. Like this, patch does not accept 11000-by-3 RGB triplets.
close all;
n = 10;
theta = (0:n-1)*(2*pi/n);
X = (pc(:,1) + r.*cos(theta));
Y = (pc(:,2) + r.*sin(theta));
patch(X',Y',(RGB(:,1)/255),'EdgeColor','none','FaceAlpha',.5);
% ^ notice only 1 column, not 3
xlim([0 1920]);
ylim([0 1080]);
EDIT
After an hour I finally figured out on how to use the options 'Faces' and 'Vertices' properly so I can use the 11000-by-M RGB triplets
close all;
n = 100;
theta = (0:n-1)*(2*pi/n);
X = (pc(:,1) + r.*cos(theta));
Y = (pc(:,2) + r.*sin(theta));
for i = 1:(size(pc,1))
vertices = [X(i,:)' Y(i,:)'];
faces = 1:n;
patch('Faces',faces,...
'Vertices',vertices,...
'FaceVertexCData',(RGB(i,:)/255),...
'FaceColor','flat',...
'EdgeColor','none');
end
xlim([0 1920]);
ylim([0 1080]);
So ^ code works now. I don't think I can get rid of the loop, so this will be the final result.
Thank you for all your help.
Bruno Luong
Bruno Luong on 21 Oct 2018
Edited: Bruno Luong on 21 Oct 2018
To remove the for-loop, you can still set RGB via colormap (kind of overkill to have one color by circle)
n = 50;
theta = (0:n-1)*(2*pi/n);
nc = 11000;
xc = rand(nc,1);
yc = rand(nc,1);
r = 1e-3+0.025*rand(nc,1);
X = xc + r.*cos(theta);
Y = yc + r.*sin(theta);
close all
RGB = rand(nc,3); % one RGB per circle
colormap(RGB);
C = rand(1,nc); % patch with random face color
patch(X',Y',(1:nc),'EdgeColor','none','FaceAlpha',0.7);
set(gca,'clim',[0.5 nc+0.5]);
axis equal

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 21 Oct 2018
One way is to use poly2mask() several times, ORing them together, to get a binary image of all shapes. Then use bwlabel() to get each region a different ID label (number). Then use label2rgb() to give each region a unique color.
binaryImage = false(rows, columns);
for k = 1 : numRegions
% Somehow get the x and y for this particular shape
x = ....
y = ....
binaryImage = binaryImage | poly2mask(x, y, rows, columns);
end
labeledImage = bwlabel(binaryImage);
rgbImage = label2rgb(labeledImage, yourColorMap);
Create your colormap as a numRegions by 3 array of color numbers in the range 0-1.
  1 Comment
YT
YT on 21 Oct 2018
Well making a mask of the shape is not really the same as actually making a polygon itself. I didn't know what 'rows' and 'columns' was supposed to be here, but assumed the matrix/image dimensions. In combination with the answer of @Bruno on how to get coordinates for circles, I put the following together.
n = 50;
theta = (0:n-1)*(2*pi/n);
yourColorMap = RGB/255; %RGB M-by-3 color matrix
img = imread('...'); %image
[rows,columns,~] = size(img);
binaryImage = false(rows, columns);
numRegions = size(pc,1); %pc(:,1) = x; pc(:,2) = y
for k = 1 : numRegions
% Somehow get the x and y for this particular shape
x = pc(k,1) + r(k)*cos(theta); %pc(k,1) = x-coordinate circle
y = pc(k,2) + r(k)*sin(theta); %pc(k,2) = y-coordinate circle
binaryImage = binaryImage | poly2mask(x, y, rows, columns);
end
labeledImage = bwlabel(binaryImage);
rgbImage = label2rgb(labeledImage, yourColorMap);
imshow(rgbImage);
The image contains white pixels (which arent clearly visible) but that's it. I think this method is not going to work in this case.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!