Model of a crowd on concert venue or how to distribute random points according to the 2D window distribution

조회 수: 6 (최근 30일)
Hello
Could you please help me with the following issue: I need to "simulate" the crowd in a concert venue by the set of cylinders ( for example with height of 1.7 m and radius of 0.25 m with different concentration (number of cylinders per m^2) ).
In fact the task is to find the coordinates (x, y) of these cylinders.
In real case concentration of people decreases to the edges of the venue and to its back part. For example near the stage we have 2 pers/m^2 and it decreases to 0 (no people) to the edges of the venue and to its back part. Attached picture is an example what I need to do, but there is a constant concentration. пример.jpg
Using a 2D window, I modeled a change in concentration on the venue (I attach a picture and a mat file) concentration.jpg
contourf(x, y, Nu, 'ShowText','on')
shading interp
xlabel('X (Length), m')
ylabel('Y (Width), m')
title('People concentration variation through the venue')
colorbar
Now, according to this distribution, I need to find the coordinates of the points (in fact coordinates of the cylinders.) ... and these points should be randomly placed within a given concentration, I mean not in line as an array ... that is, in fact, I need to simulate more or less real placement of crowd.
To understand better I need to do something like this пример1.JPG https://www.mathworks.com/matlabcentral/answers/374345-how-to-distribute-random-points-according-to-the-epanechnikov-distribution-values but taking into account than cylinders have a radius of 0.25 m.
I will be very grateful! Because I can not figure out how to do it.
Thank you! If it's not clear, don't hesitate to ask me, because I really hope for your help!
  댓글 수: 1
Torsten
Torsten 2018년 11월 28일
Discard the choice of a random point if the minimum distance to the points already generated is smaller than 0.5.

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

답변 (1개)

Bruno Luong
Bruno Luong 2018년 11월 28일
편집: Bruno Luong 2019년 9월 26일
Torsten's rejection might bias the distribution.
One of the better approach is to repell the points when they are close to each other. The constraints are not always meet but it's very reasonable overall.
You can run Torsten's rejection afterward if needed. Otherwise consider the overlapping circles as mom carrying her baby :-).
L = 20; % <-- Choose length of square sides
x0 = L/2; y0 = L/2; % <-- Choose center of square
n = 500; % <-- Choose number of points
% Generate 2D epanechnikov-distribution
X = [x0,y0] + (sin(asin(2*rand(n,2)-1)/3))*L;
XYR = [x0,y0]+[[-1;1;1;-1;-1],[-1;-1;1;1;-1]]*L/2;
XB = interp1((0:4)'*L,XYR,linspace(0,4*L,200));
XB(end,:) = [];
nrepulsion = 50;
% Repulsion of seeds to avoid them to be too close to each other
n = size(X,1);
Xmin = [x0-L/2,y0-L/2];
Xmax = [x0+L/2,y0+L/2];
% Point on boundary
XR = x0+[-1,1,1,-1,-1]*L/2;
YR = y0+[-1,-1,1,1,-1]*L/2;
cla;
hold on
plot(XR,YR,'r-');
h = plot(X(:,1),X(:,2),'b.');
axis equal
dmin = 0.5;
d2min = dmin*dmin;
beta = 0.5;
for k = 1:nrepulsion
XALL = [X; XB];
DT = delaunayTriangulation(XALL);
T = DT.ConnectivityList;
containX = ismember(T,1:n);
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)],[n 1],@(x) {x});
maxd2 = 0;
R = zeros(n,2);
move = false(n,1);
for i=1:n
Ti = T{i};
P = X(i,:) - XALL(Ti,:);
nP2 = sum(P.^2,2);
if any(nP2<2*d2min)
move(i) = true;
move(Ti(Ti<=n)) = true;
end
maxd2 = maxd2 + mean(nP2);
b = Ti > n;
nP2(b) = nP2(b)*5; % reduce repulsion from each point of the border
R(i,:) = sum(P./max((nP2-d2min),1e-3),1);
end
if ~any(move)
break
end
if k==1
v0 = (L*5e-3)/sqrt(maxd2/n);
end
R = R(move,:);
v = v0/sqrt(max(sum(R.^2,2)));
X(move,:) = X(move,:) + v*R;
% Project back if points falling outside the rectangle
X = min(max(X,Xmin),Xmax);
set(h,'XData',X(:,1),'YData',X(:,2));
pause(0.01);
end
theta = linspace(0,2*pi,65);
xc = dmin/2*sin(theta);
yc = dmin/2*cos(theta);
% plot circles f diameter dmin around random points
for i=1:n
plot(X(i,1)+xc,X(i,2)+yc,'k');
end
  댓글 수: 2
Harshil Pisavadia
Harshil Pisavadia 2019년 6월 1일
편집: Harshil Pisavadia 2019년 6월 1일
Hey Bruno
Just wondering, is there a way to modify this code to be able to work in a 3D space?
Thanks!
Bruno Luong
Bruno Luong 2019년 6월 3일
If I'm not mistaken, each statement of my code could be converted to 3D counter part. You migh adjust some hard code constant for the convergence.

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

카테고리

Help CenterFile Exchange에서 Random Number Generation에 대해 자세히 알아보기

태그

제품


릴리스

R2017b

Community Treasure Hunt

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

Start Hunting!

Translated by