random polygons inside a semi-circle

3 vues (au cours des 30 derniers jours)
jahanzaib ahmad
jahanzaib ahmad le 25 Oct 2018
Commenté : jahanzaib ahmad le 28 Juin 2019
how to generate 2D random convex polygons inside a semi-circle 150mm diameter.the size of polygons should have a limit . maximum length of side of polygons is between 5 to 10 mm not smaller nor larger
  4 commentaires
Guillaume
Guillaume le 25 Oct 2018
Please, don't write in all caps. It's very difficult to read.
jahanzaib ahmad
jahanzaib ahmad le 25 Oct 2018
i have used this code to generate polygons now i want to place them randomly in semi circles and want to fix there size as well
x1 = rand(1,10); y1 = rand(1,10);
vi = convhull(x1,y1); polyarea(x1(vi),y1(vi))
plot(x1,y1,'.') axis equal hold on fill ( x1(vi), y1(vi), 'r','facealpha', 0.5 ); hold off

Connectez-vous pour commenter.

Réponse acceptée

Bruno Luong
Bruno Luong le 25 Oct 2018
Modifié(e) : Bruno Luong le 28 Oct 2018
Edit code:
  1. make polygon more uniform in size at the trade off of randomness remove artifact of the border.
  2. adjust repulsion parameters.
  3. improve sticky-border artifact due to denser points
N = 100; % aproximative number of polygonals to be generated
n = 64; % control size and number of vertexes of polygonal
nrepulsion = 8; % control the size of the polygonal and the randomness of the position
X = randn(N,2);
R = sqrt(rand(N,1));
X = R .* X ./ sqrt(sum(X.^2,2));
X(:,2) = abs(X(:,2));
nb = 100;
theta = linspace(0,pi,nb)';
XC = [cos(theta), sin(theta)];
nb = ceil(nb*2/pi);
XY0 = linspace(-1,1,nb)' .* [1 0];
XY0([1 end],:) = [];
n1 = size(X,1);
n2 = size(XC,1);
n3 = size(XY0,1);
CC = n1+(1:n2-1)' + [0 1];
C0 = (n1+n2)+(1:n3-1)' + [0 1];
C = [CC; C0];
XB = [XC; XY0];
% Repulsion of seeds to avoid them to be too close to each other
for k = 1:nrepulsion-1
XALL = [X; XB];
DT = delaunayTriangulation(XALL);
T = DT.ConnectivityList;
containX = ismember(T,1:n1);
b = any(containX,2);
TX = T(b,:);
[r,i0] = find(containX(b,:));
i = mod(i0+(-1:1),3)+1;
i = TX(r + (i-1)*size(TX,1));
T = accumarray([i(:,1);i(:,1)],[i(:,2);i(:,3)],[n1 1],@(x) {x});
maxd2 = 0;
R = zeros(n1,2);
for i=1:n1
Ti = T{i};
P = X(i,:) - XALL(Ti,:);
nP2 = sum(P.^2,2);
maxd2 = maxd2 + mean(nP2);
b = Ti > n1;
nP2(b) = nP2(b)*3; % reduce repulsion from each point of the border
R(i,:) = sum(P./nP2,1);
end
if k==1
v0 = 0.005/sqrt(maxd2/n1);
end
v = v0/sqrt(max(sum(R.^2,2)));
X = X + v*R;
% Project back if points falling outside the half-circle
X(:,2) = max(X(:,2),0.01);
r2 = sum(X.^2,2);
out = r2>1;
X(out,:) = X(out,:) .* (0.99 ./ sqrt(r2(out)));
end
DT = delaunayTriangulation(X);
[V,P] = voronoiDiagram(DT);
KX = convexHull(DT);
[ib,ik] = ismember(1:N,KX);
r = 2;
r2 = r^2;
warning('off','MATLAB:polyshape:boundary3Points');
warning('off','MATLAB:polyshape:repairedBySimplify');
PXB = polyshape(XC);
for k=1:N
Pk = V(P{k},:);
if ib(k) % infinity
ik0 = ik(k);
if ik0 == length(KX)
kp = KX(1);
else
kp = KX(ik0+1);
end
km = k;
Pv = Pk(2,:);
if Pv*Pv' < r2
t = X(km,:)-X(kp,:);
nt2 = t*t';
P0 = t*((Pv*t')/nt2);
cs2 = P0*P0';
if cs2 <= r2
d = [-t(2),t(1)] / sqrt(nt2);
sn = sqrt(r2-cs2);
if sn > (Pv-P0)*d'
Pk(1,:) = P0 + sn*d;
else
Pk(1,:) = [];
end
else
Pk(1,:) = [];
end
else
Pk(1,:) = [];
end
if ik0 == 1
km = KX(end);
else
km = KX(ik0-1);
end
kp = k;
Pv = Pk(end,:);
if Pv*Pv' < r2
t = X(km,:)-X(kp,:);
nt2 = t*t';
P0 = t*((Pv*t')/nt2);
cs2 = P0*P0';
if cs2 <= r2
d = [-t(2),t(1)] / sqrt(nt2);
sn = sqrt(r2-cs2);
if sn > (Pv-P0)*d'
Pk(end+1,:) = P0 + sn*d;
end
end
end
end
[Pk,sid] = intersect(PXB, polyshape(Pk));
Pk = Pk.Vertices;
m = length(Pk);
if m >= 3
nb1 = sum(sid == 1);
m = m - nb1;
W = rand(n,m-1) .^ (1./(m-1:-1:1));
W = cumprod([ones(n,1),W],2) .* (1-[W, zeros(n,1)]);
if nb1>0
% Consider weight of the borders as weight for two points
Pk = circshift(Pk,-find(sid==0, 1, 'first'),1);
nb1 = nb1+2;
w = linspace(0,2/nb1,nb1);
Pk = [Pk(1:m-2,:); [w; fliplr(w)]*Pk(m-1:end,:)];
end
Pk = W*Pk;
K = convhull(Pk);
P{k} = Pk(K,:);
else
P{k} = [];
end
end
P(cellfun('isempty',P)) = [];
% Check
fig = figure(1);
clf(fig);
ax = axes('Parent',fig);
hold(ax,'on');
plot(ax, XB([1:end 1],1),XB([1:end 1],2),'k');
for k=1:length(P)
Pk = P{k};
fill(ax,Pk(:,1),Pk(:,2),k);
end
axis(ax,'equal');
axis(ax,[-1.1 1.1 -0.1 1.1]);
  7 commentaires
Bruno Luong
Bruno Luong le 9 Nov 2018
Modifié(e) : Bruno Luong le 9 Nov 2018
If you want to increase the spacing between random polygonal you might shrink Pk (after shift the origin to the seed X(k,:)
Pk = X(k,:) + 0.5*(Pk - X(k,:)); % 0.5 is adjustable constant in (0,1)
right before the statement
Pk = W*Pk;
Not sure to understand your question about circle but I think you might open a new question with better description. It looks like an unrelated problem after formulation.
jahanzaib ahmad
jahanzaib ahmad le 20 Nov 2018
Modifié(e) : jahanzaib ahmad le 20 Nov 2018
@bruno
i want to two different size only like 10 mm and 5 mm and not more then that and not less then that .or two fixed area ± 20 percent and skip the other sizes/areas in between ,
i have tried to do this generating random numbers twice .this is ur first code u uploaded ..(my exact problem is that 30 percent area of semi circle should be covered with same 5 mm±2mm polygons and 40 percent should be covered with 10mm ±2mm)
N = 10; % aaproximative Number of polygonals
n = 200; % control size and number of vertexes of polygonal
X = randn(N,2);
R = sqrt(rand(N,1));
X = R .* X ./ sqrt(sum(X.^2,2));
X(:,2) = abs(X(:,2));
nb = max(N,100);
theta = linspace(0,pi,nb)';
XC = [cos(theta), sin(theta)];
%XY0 = linspace(-1,1,nb)' .* [1 0];
%XY0([1 end],:) = [];
XALL = [X; XC];
n1 = size(X,1);
n2 = size(XC,1);
%n3 = size(XY0,1);
CC = n1+(1:n2-1)' + [0 1];
%C0 = (n1+n2)+(1:n3-1)' + [0 1];
C = [CC];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
N1 = 10; % aaproximative Number of polygonals
n11 = 50; % control size and number of vertexes of polygonal
X1 = randn(N1,2);
R1 = sqrt(rand(N1,1));
X1 = R1 .* X1 ./ sqrt(sum(X1.^2,2));
X1(:,2) = abs(X1(:,2));
nb1 = max(N1,100);
theta1 = linspace(0,pi,nb1)';
XC1 = [cos(theta1), sin(theta1)];
XY01 = linspace(-1,1,nb1)' .* [1 0];
XY01([1 end],:) = [];
X1ALL = [X1; XC1; XY01];
n111 = size(X1,1);
n21 = size(XC1,1);
n31 = size(XY01,1);
CC1 = n111+(1:n21-1)' + [0 1];
C01 = (n111+n21)+(1:n31-1)' + [0 1];
C1 = [CC1; C01];
C3 = [C;C1];
X3 = [X1ALL;XALL] ;
DT = delaunayTriangulation(X3, C3);
[V,r] = voronoiDiagram(DT);
yV1 = V(:,2);
xV1 = V(:,1);
inside1 = (yV1 > 0) & (xV1.^2+yV1.^2) < 1;
inside1 = cellfun(@(ab) all(inside1(ab)), r);
r = r(inside1);
for k=1:length(r)
rk = r{k};
m1 = length(rk);
W1 = rand(m1-1,n) .^ (1./(m1-1:-1:1)');
W1 = cumprod([ones(1,n);W1]) .* (1-[W1; zeros(1,n)]);
W2 = rand(m1-1,n11) .^ (1./(m1-1:-1:1)');
W2 = cumprod([ones(1,n11);W2]) .* (1-[W2; zeros(1,n11)]);
%rk = X(k,:) + 0.9*(rk - X(k,:)); this line is not working with this
%code
W=[W1 W2];
P = W'*V(rk,:);
K1 = convhull(P);
r{k} = P(K1,:);
end
% Check
close all
hold on
XB1 = [XC1; XY01];
plot(XB1([1:end 1],1),XB1([1:end 1],2),'b');
for k=1:length(r)
rk = r{k};
plot(rk([1:end 1],1),rk([1:end 1],2),'g');
end
axis equal;
axis([-1.1 1.1 -0.1 1.1]);
%%%%%%%%%%%%%%%%%%%%%%
if value of n11 > n and N>N1 OVERLAPPING also happens .PLEASE

Connectez-vous pour commenter.

Plus de réponses (1)

jahanzaib ahmad
jahanzaib ahmad le 1 Jan 2019
  5 commentaires
jahanzaib ahmad
jahanzaib ahmad le 13 Jan 2019
is this possible to get constant size polygons ? or to minimize the variation in size ?
jahanzaib ahmad
jahanzaib ahmad le 28 Juin 2019
@Bruno
Edit code:
  1. make polygon more uniform in size at the trade off of randomness remove artifact of the border.
  2. adjust repulsion parameters.
  3. improve sticky-border artifact due to denser points
i tried to make a 3D buts it do not have the above mentioned qualities .i want to make the tetrahedron big enough that do not intersect but i want to control the number of vertices (maximum should be 15 ). plus uniform distribution inside cube .
N=250;
X=rand(N,3);
n=80;
my_vertices = [0 0 0; 0 1 0; 1 1 0; 1 0 0; 0 0 1; 0 1 1; 1 1 1; 1 0 1];
XALL=[X;my_vertices];
n1 = size(X,1);
DT = delaunayTriangulation(XALL(:,1),XALL(:,2),XALL(:,3));
%triplot(DT)
[V,r] = voronoiDiagram(DT);
yV = V(:,2);
xV = V(:,1);
zV=V(:,3);
%plot(xV,yV,'b-');
inside = (yV>0)&(yV<1)& (xV<1)& (xV > 0) &(zV<1)& (zV > 0) ;
inside = cellfun(@(id) all(inside(id)), r);
r = r(inside);
for k=1:length(r)
rk = r{k};
m = length(rk);
W = rand(m-1,n) .^ (1./(m-1:-1:1)');
W = cumprod([ones(1,n);W]) .* (1-[W; zeros(1,n)]);
%P = W'*V(rk,:);
% P = V(rk,:)- .0000001.*V(rk,:);
P =W'* (V(rk,:));
%P = W'*P;
K = convhull(P);
r{k} = P(K,:);
% plot(P(:,1),P(:,2),'.');
%hold on
end
figure(1)
for k=1:length(r)
rk = r{k};
DT3 = delaunayTriangulation(rk);
[C3,v3]= convexHull(DT3);
trisurf(C3,DT3.Points(:,1),DT3.Points(:,2),DT3.Points(:,3),'FaceColor','w');
hold on
end

Connectez-vous pour commenter.

Catégories

En savoir plus sur Elementary Polygons dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by