scatter randomized points with circles

12 views (last 30 days)
Marwen Tarhouni
Marwen Tarhouni on 14 Feb 2017
Commented: Jan on 24 Feb 2017
Hello,
How we can draw circles of radius R on randomized points in a area100*100? Knowing that its points are located in the following way:
The minimum distance between all points> 6 meters.
do you have an idea ?
Thank you
  1 Comment
Jan
Jan on 14 Feb 2017
What is the difference to your question https://www.mathworks.com/matlabcentral/answers/322431-randompoints-condition-distance? Do you have the coordinates of the points already and only want to draw the circles?

Sign in to comment.

Accepted Answer

John BG
John BG on 20 Feb 2017
Hi Marwen
Here are 2 functions that solve the question, not randomly guessing points from the entire area, but excluding gradually the area sized by already allocated points:
function [X,Y,Nmax,Dmatrix,delay]=scatter_points7(void)
% given H and W size of 2D rectangle scatter_points7.m does the following:
% 1. calculate Nmax, the maximum amount of circles radius R0 that orderly fit in rectangle HxW
% 2. scatter Ap random points with spatial resolution dx =- 0.1 and dy=0.1
% and spaced at least distance R0
% if requested amount Ap>Nmax rand2Dpoints breaks because there
% is no space to fit in so many random points complying with min
% distance R0
% 3. calculate distance matrix Dmatrix among all points
% 4. return the coordinates of all generated points in X and Y, along with Dmatrix and Nmax
% 5. plot points
% 6. plot safety circles to visually verify
%
% the amount of generated points is numel(X) and cannot be larger than Nmax
% because of the request for the points to be randomly generated.
%
% in this initial version, only manual input through message box.
%
% call examples:
% 1.
% [X,Y,Dmatrix,Nmax]=scatter_points7
%
% 2.
% [X,Y,Nmax]=scatter_points7
% 2 examples how to verify distance values and check distances meet requirement > R0
% 1.
% L=combinator(Ap,2,'c');
% relD2=((X(L(:,2))-X(L(:,1))).^2+(Y(L(:,2))-Y(L(:,1))).^2).^.5
% find(relD2<R0)
%
% 2.
% L2=combinator(Ap,2);
% Dmatrix=reshape(((X(L2(:,2))-X(L2(:,1))).^2+(Y(L2(:,2))-Y(L2(:,1))).^2).^.5,[Ap Ap]);
% Dmatrix([1:21:end])=NaN ;
% Dmatrix(Dmatrix<6)
%
% February 10th 2017
% version: 1.0
% author: John Bofarull Guix, any feedback to build next version is welcome at
% jgb2012@sky.com or through the Mathworks website
% this script was inspired by Mr Marwen Tarhoumi marwentarhoumi@rocketmail.com
% and Matt Fig's popkenai@yahoo.com mighty function combinator.m available
% from Mathworks File exchange
clear all;clc;close all
format bank
rng('Shuffle')
prompt = {'rectangle width W: ','rectange height H: ','amount points to scatter: ','safety distance Radius: '};
dlg_title = 'Input';
num_lines = 1;
defaultans = {'100','100','20','3'};
input_answer = inputdlg(prompt,dlg_title,num_lines,defaultans);
Diam0=2*str2double(input_answer{4});
W=str2double(input_answer{1})+Diam0;
H=str2double(input_answer{2})+Diam0;
Ap=str2double(input_answer{3});
Ap=floor(Ap);
Nmax=calc_amount_circles(W-Diam0,H-Diam0,Diam0/2);
fprintf('\nRectangle %f x %f has\n max capacity: %i circles radius %f\n',W-Diam0,H-Diam0,Nmax,Diam0/2);
if Nmax<Ap
fprintf('\nCannot fit in more than %i circles.\n',Nmax);
X=0;Y=0;Nmax=0;Dmatrix=0;
return;
end % error message in case requested amount points above Nmax
As=21; % amount sides polygon approximating circles
a=linspace(0,2*pi,As); % angle for circles
dx=1;dy=1;refine=0;
X=zeros(1,Ap);Y=zeros(1,Ap);
if W*H>=900^2
dx=1;dy=1;
refine=1;
else
dx=.1;dy=.1;
refine=0;
end
x_grid=[(-W+Diam0)/2:dx:(W-Diam0)/2];y_grid=[(-H+Diam0)/2:dy:(H-Diam0)/2]; % avoid circles hitting frame
[X_grid,Y_grid]=meshgrid(x_grid,y_grid);
P=[X_grid(:)';Y_grid(:)'];[sz1P,sz2P]=size(P);
if refine==0
xc2_base=Diam0/2*cos(a);yc2_base=Diam0/2*sin(a);
elseif refine==1
xc2_base=(Diam0/2+1)*cos(a);yc2_base=(Diam0/2+1)*sin(a);
end
figure;ax=gca;ax.DataAspectRatio=[1 1 1];
ax.XLim=[-W/2 W/2];ax.YLim=[-H/2 H/2];
ax.XTick=[(-W+Diam0)/2:10:(W-Diam0)/2];ax.YTick=[(-H+Diam0)/2:10:(H-Diam0)/2];grid on;hold all;
perimeter=[(-W+Diam0)/2-.25 (W-Diam0)/2+.25 (W-Diam0)/2+.25 (-W+Diam0)/2-.25 (-W+Diam0)/2-.25;
(-H+Diam0)/2-.25 (-H+Diam0)/2-.25 (H-Diam0)/2+.25 (H-Diam0)/2+.25 (-H+Diam0)/2-.25];
plot(perimeter(1,:),perimeter(2,:),'Color',[.3 .3 .3]);
tic;
for k=1:1:Ap
[sz1P,sz2P]=size(P);
if sz2P>0
nP = randi(sz2P,1,1);
else
break
end
if refine==0
X(k)=P(1,nP);Y(k)=P(2,nP);
elseif refine==1
dec_xP=randi([0 499],1,1);dec_xP=dec_xP/1e3; % worst case added jitter bringing 2 points on crash course
dec_yP=randi([0 499],1,1);dec_yP=dec_yP/1e3;
X(k)=P(1,nP)+dec_xP;Y(k)=P(2,nP);Y(k)=P(2,nP)+dec_yP;
end
xc2=xc2_base+X(k);yc2=yc2_base+Y(k);
in=inpolygon(P(1,:),P(2,:),xc2,yc2);
P(:,find(in>0))=[]; % exclude area already busy
figure(1);plot(X(k),Y(k),'r*'); % centre circles
figure(1);plot(xc2,yc2,'Color',[0.8 0.8 1]); % circles radius Diam0/2
end
L2=combinator(Ap,2); % test 2
Dmatrix=reshape(((X(L2(:,2))-X(L2(:,1))).^2+(Y(L2(:,2))-Y(L2(:,1))).^2).^.5,[Ap Ap]);
Dmatrix([1:Ap+1:end])=NaN ;
hold off
delay=toc;
end
function Anxny=calc_amount_circles(H_,L_,D_)
% calculates 1. amount of circles in hex pattern that fit within 2D rectangle L (columns) x H (tall, lines or rows)
% used graph from http://www.engineeringtoolbox.com/circles-within-rectangle-d_1905.html to calibrate
R_=D_/2;
if L_<(2*R_)
Nx=0;
else Nx=floor(L_/(2*R_));
end;
if H_<(2*R_)
Ny=0;
else
s=1;
while H_/(2*R_+s*R_*3^.5)>1;
s=s+1;
end
Ny=s;
end;
if rem(L_,2*R_)>=R_
min1_evenlines=0;
else min1_evenlines=1;
end;
Anxny=Nx*Ny-floor(Ny/2)*min1_evenlines;
end
%
% function handling_input_errors
% % input checks
% narginchk(5,5);nargoutchk(4,4);
%
% err_message={'error input type W';'error input type H';'error input type R0';'error input type R0';'error input saturate'};
%
% if(~isreal(H) || ~isscalar(W) || W<=0 )
% error(err_message{1});
% end
% if(~isreal(H) || ~isscalar(H) || H<=0 )
% error(err_message{2});
% end
% if(~isreal(R0) || ~isscalar(R0) || R0<=0 )
% error(err_message{3});
% end
%
% if(~isreal(Ap) || ~isscalar(Ap) || Ap<=0 )
% error(err_message{3});
% end
% if(~isreal(saturate) || ~isscalar(saturate) || saturate<0 || saturate>1)
% error(err_message{3});
% end
% end
and the saturation:
function [X,Y,Nmax,Dmatrix]=scatter_points_saturate(W0,H0,R0)
% scatter_points_saturate.m
% given H and W size of 2D rectangle scatter_points7.m does the following:
% 1. calculate Nmax, the maximum amount of circles radius R0 that orderly fit in rectangle HxW
% 2. scatter as many random points as possible with spatial resolution dx =- 0.1 and dy=0.1
% and spaced at least distance R0
% 3. calculate distance matrix Dmatrix among all points
% 4. return the coordinates of all generated points in X and Y, along with Dmatrix and Nmax
% 5. plot points
% 6. plot safety circles to visually verify
%
% the amount of generated points is numel(X) and cannot be larger than Nmax
%
%
% call examples:
% 1.
% [X,Y,Dmatrix,Nmax]=scatter_points_saturate(100,100,3)
%
% 2.
% [X,Y,Nmax]=scatter_points7
% 2 examples how to verify distance values and check distances meet requirement > R0
% 1.
% L=combinator(Ap,2,'c');
% relD2=((X(L(:,2))-X(L(:,1))).^2+(Y(L(:,2))-Y(L(:,1))).^2).^.5
% find(relD2<R0)
%
% 2.
% L2=combinator(Ap,2);
% Dmatrix=reshape(((X(L2(:,2))-X(L2(:,1))).^2+(Y(L2(:,2))-Y(L2(:,1))).^2).^.5,[Ap Ap]);
% Dmatrix([1:21:end])=NaN ;
% Dmatrix(Dmatrix<6)
%
% February 10th 2017
% version: 1.0
% author: John Bofarull Guix, any feedback to build next version is welcome at
% jgb2012@sky.com or through the Mathworks website
% this script was inspired by Mr Marwen Tarhoumi marwentarhoumi@rocketmail.com
% and Matt Fig's popkenai@yahoo.com mighty function combinator.m available
% from Mathworks File exchange
% clear all;clc;close all
% format bank
% rng('Shuffle')
% R0=35
Diam0=2*R0; % distance requirement among adjacent points not to be closer than
% W0=50
% H0=70
W=W0+Diam0; % rectangle width, columns
H=H0+Diam0; % rectangle tall, row
Nmax=calc_amount_circles(W0,H0,Diam0/2)
Ap=20
As=21; a=linspace(0,2*pi,As);xc=Diam0*cos(a);yc=Diam0*sin(a);
dx=1;dy=1;
X=zeros(1,Ap);Y=zeros(1,Ap);
if W*H>=1e6
dx=1;dy=1;
else dx=.1;dy=.1;
end
X=zeros(1,Ap);Y=zeros(1,Ap);
x_grid=[-W0/2:dx:W0/2];y_grid=[-H0/2:dy:H0/2]; % avoid circles hitting frame
[X_grid,Y_grid]=meshgrid(x_grid,y_grid);
% X_grid0=X_grid;Y_grid0=Y_grid;
P=[X_grid(:)';Y_grid(:)'];[sz1P sz2P]=size(P);
xc2_base=Diam0/2*cos(a);yc2_base=Diam0/2*sin(a);
% xc1_base=Diam0*cos(a);yc1_base=Diam0*sin(a);
figure;ax=gca;ax.DataAspectRatio=[1 1 1]
ax.XLim=[-W/2 W/2];ax.YLim=[-H/2 H/2];
ax.XTick=[(-W+Diam0)/2:10:(W-Diam0)/2];ax.YTick=[(-H+Diam0)/2:10:(H-Diam0)/2];grid on;hold all;
perimeter=[(-W+Diam0)/2-.25 (W-Diam0)/2+.25 (W-Diam0)/2+.25 (-W+Diam0)/2-.25 (-W+Diam0)/2-.25;
(-H+Diam0)/2-.25 (-H+Diam0)/2-.25 (H-Diam0)/2+.25 (H-Diam0)/2+.25 (-H+Diam0)/2-.25];
plot(perimeter(1,:),perimeter(2,:),'Color',[.3 .3 .3]);
k=1
while sz2P>Diam0*.2
k=k+1;
[sz1P sz2P]=size(P);
if sz2P>0
nP = randi(sz2P,1,1);
else
break
end
X(k)=P(1,nP);Y(k)=P(2,nP);
% xc1=xc1_base+X(k);yc1=yc1_base+Y(k);
xc2=xc2_base+X(k);yc2=yc2_base+Y(k);
in=inpolygon(P(1,:),P(2,:),xc2,yc2);
in=in(:)';P(:,find(in>0))=[]; % exclude area already busy
figure(1);plot(X(k),Y(k),'g*'); % centre circles
figure(1);plot(xc2,yc2,'Color',[0.7 .9 0.7]); % circles radius Diam0/2
end
L2=combinator(Ap,2); % test 2
Dmatrix=reshape(((X(L2(:,2))-X(L2(:,1))).^2+(Y(L2(:,2))-Y(L2(:,1))).^2).^.5,[Ap Ap]);
Dmatrix([1:Ap+1:end])=NaN ;
end
function Anxny=calc_amount_circles(H_,L_,D_)
% calculates 1. amount of circles in hex pattern that fit within 2D rectangle L (columns) x H (tall, lines or rows)
% used graph from http://www.engineeringtoolbox.com/circles-within-rectangle-d_1905.html to calibrate
R_=D_/2;
if L_<(2*R_)
Nx=0;
else Nx=floor(L_/(2*R_));
end;
if H_<(2*R_) Ny=0;
else
s=1;
while H_/(2*R_+s*R_*3^.5)>1;
s=s+1;
end
Ny=s;
end;
if rem(L_,2*R_)>=R_
min1_evenlines=0;
else min1_evenlines=1;
end;
Anxny=Nx*Ny-floor(Ny/2)*min1_evenlines;
end
function handling_input_errors
narginchk(5,5);nargoutchk(4,4);
err_message={'error input type W';'error input type H';'error input type R0';'error input type R0';'error input saturate'}
if(~isreal(H) || ~isscalar(W) || W<=0 ) error(err_message{1}); end
if(~isreal(H) || ~isscalar(H) || H<=0 ) error(err_message{2}); end
if(~isreal(R0) || ~isscalar(R0) || R0<=0 ) error(err_message{3}); end
Ap=floor(Ap); if(~isreal(Ap) || ~isscalar(Ap) || Ap<=0 ) error(err_message{3}); end
if(~isreal(saturate) || ~isscalar(saturate) || saturate<0 || saturate>1) error(err_message{3}); end
end
the function combinator is available from here
attached scatter_points7.m and scatter_points_saturate.m
Appreciating time and attention
John Bofarull Guix

More Answers (2)

Jan
Jan on 14 Feb 2017
Edited: Jan on 20 Feb 2017
nWant = 20;
Dist = 6;
[X, Y] = GetPointsRandom(nWant, 100, 100, Dist);
alpha = linspace(0, 2*pi, 32).';
% cx = X.' + 0.5 * Dist * cos(alpha); % Matlab >= 2016b
% cy = Y.' + 0.5 * Dist * sin(alpha); % Matlab >= 2016b
cx = bsxfun(@plus, X.', 0.5 * Dist * cos(alpha));
cy = bsxfun(@plus, Y.', 0.5 * Dist * sin(alpha));
figure;
AxesH = axes('NextPlot', 'add');
plot(cx, cy, 'b', 'Parent', AxesH);
axis equal
set(AxesH, 'XLim', [0, 100], 'YLim', [0, 100]);
  7 Comments
Jan
Jan on 24 Feb 2017
@John: The question was:
How we can draw circles of radius R on randomized points in
a area 100*100?
Then the center is "a detail [which] has not been mentioned".

Sign in to comment.


KSSV
KSSV on 14 Feb 2017
  2 Comments
KSSV
KSSV on 14 Feb 2017
That link....creates pints.....around those points circles can be drawn. Isn't it?

Sign in to comment.

Tags

No tags entered yet.

Products

Community Treasure Hunt

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

Start Hunting!