scatter randomized points with circles

조회 수: 6 (최근 30일)
Marwen Tarhouni
Marwen Tarhouni 2017년 2월 14일
댓글: Jan 2017년 2월 24일
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
Jan
Jan 2017년 2월 14일
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?

댓글을 달려면 로그인하십시오.

채택된 답변

John BG
John BG 2017년 2월 20일
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

추가 답변 (2개)

Jan
Jan 2017년 2월 14일
편집: Jan 2017년 2월 20일
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
John BG
John BG 2017년 2월 23일
the centre points are not 'a detail' but the utmost important point, it's the first thing you should plot when considering visual presentation of anything attempting to answer this and similar questions.
John BG
Jan
Jan 2017년 2월 24일
@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".

댓글을 달려면 로그인하십시오.


KSSV
KSSV 2017년 2월 14일
  댓글 수: 2
Marwen Tarhouni
Marwen Tarhouni 2017년 2월 14일
@KSSV, I want to create circles surrounding random points and The minimum distance between all points> 6 meters.
KSSV
KSSV 2017년 2월 14일
That link....creates pints.....around those points circles can be drawn. Isn't it?

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Scatter Plots에 대해 자세히 알아보기

태그

아직 태그를 입력하지 않았습니다.

제품

Community Treasure Hunt

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

Start Hunting!

Translated by