Create polygons from circles x, y and radii

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

While this looks like something I was looking for, it does not work for my circles.
Warning: Output contains an empty polyshape due to duplicate vertices, intersections, or other
inconsistencies.
> In polyshape/checkAndSimplify (line 411)
In polyshape (line 155)
Warning: Polyshape has duplicate vertices, intersections, or other inconsistencies that may produce
inaccurate or unexpected results. Input data has been modified to create a well-defined polyshape.
> In polyshape/checkAndSimplify (line 421)
In polyshape (line 155)
Do you happens to gives circle with radius==0?
GIGO
nope
>> min(r)
1.1180
>> max(r)
1.3509e+05
This is the script I derived from your answer
n = 100;
theta = (0:n-1)*(2*pi/n); %r = 11000-by-1 circle radii
XC = (pc(:,1) + r.*cos(theta)); %pc(:,1) = 11000-by-1 x-coordinates
YC = (pc(:,2) + r.*cos(theta)); %pc(:,2) = 11000-by-1 y-coordinates
for i = 1:(size(pc,1))
P = polyshape(XC(i,:)',YC(i,:)');
patch('Faces',[XC(i,:)' YC(i,:)'],'Vertices',P.Vertices,'FaceVertexCData',(RGB(i,:)/255),'FaceColor','flat','EdgeColor','none');
end
This does not patch anything because P.Vertices is empty.
No you have to loops on the circles, you can't create a bunch of circles as one polyshape.
YT
YT on 21 Oct 2018
Edited: YT on 21 Oct 2018
XC(i,:) & YC(i,:) are the coordinates for 1 circle. Example: XC(1,:) has length 100, YC(1,:) length 100. Just like in your example where x & y have length 100.
Not sure what's matter with POLYSHAPE, possibly bug again (are you sure about the radius that spans 5 decades?). Actually you do not need polyshape at all:
n = 100;
theta = (0:n-1)*(2*pi/n); %r = 11000-by-1 circle radii
nc = 1000;
xc = rand(nc,1);
yc = rand(nc,1);
r = 1e-3+0.01*rand(nc,1);
X = xc + r.*cos(theta);
Y = yc + r.*sin(theta);
close all
C = rand(1,nc); % patch with random face color
patch(X',Y',C);
axis equal
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.
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)

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

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.

Categories

Asked:

YT
on 21 Oct 2018

Edited:

on 21 Oct 2018

Community Treasure Hunt

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

Start Hunting!