在Matlab中模拟不会相互碰撞的随机游走者
Simulating random walkers which can not collide into each other in Matlab
我写了一个代码来模拟二维盒子中圆形粒子的运动。每当它们离开盒子时,我都会将它们放在盒子内并靠近墙壁。我想在代码中添加粒子的直径(2R),这意味着当两个圆心之间的距离小于2R时,它们沿着连接它们中心的线分开,使得圆心之间的距离变为等于 2R。
谁能推荐一个防止粒子重叠的代码?
这是我的代码,其中不考虑重叠:
clear all
close all
l = 224; nn = 800; %number of particles
time = 1000; dd = 1;
x= l*rand(1,nn);
y= l*rand(1,nn);
for t = 1:time;
x= x + rand(1,nn)-0.5* ones(1,nn);
y=y+rand(1,nn)-0.5* ones (1,nn);
index = (x < 0); x(index) = abs(normrnd(0,1,1,nnz(index)));
index = (y < 0); y(index) = abs(normrnd(0,1,1,nnz(index)));
index = (x > l); x(index) = l-abs(normrnd(0,1,1,nnz(index)));
index = (y > l); y(index) = l-abs(normrnd(0,1,1,nnz(index)));
end
这是一些注释代码,可以满足您的需求。特别是:
psize
是一些定义的相互作用粒子大小。
- 使用
pdist2
. 找到的点到点距离
- 距离太近的点将彼此远离一定量(
dp
乘以当前距离,如果 dp=1/2
则它们的 x 和 y 距离加倍)直到没有冲突。
详情见评论。
clear; close all;
l = 224; nn = 800; % number of particles
time = 100;
x = l*rand(1,nn); y = l*rand(1,nn);
psize = 2; % Particle size for interaction
dp = 0.1;
figure; hold on; axis([0 l 0 l]);
for t = 1:time;
% Random movement
movement = 2*rand(2,nn)-1;
x = x + movement(1,:);
y = y + movement(2,:);
index = (x < 0); x(index) = abs(normrnd(0,1,1,nnz(index)));
index = (y < 0); y(index) = abs(normrnd(0,1,1,nnz(index)));
index = (x > l); x(index) = l-abs(normrnd(0,1,1,nnz(index)));
index = (y > l); y(index) = l-abs(normrnd(0,1,1,nnz(index)));
% Particle interaction. Loop until there are no clashes. For
% robustness, some max iteration counter should be added!
numclash = 1;
while numclash > 0
dists = pdist2([x;y]', [x;y]'); % Distances between all particles
dists(dists < psize) = NaN; % Those too close are assigned NaN
tooclose = isnan(tril(dists,-1)); % All NaNs identified by logical
[clash1,clash2] = find(tooclose); % Get particles which are clashing
numclash = numel(clash1); % Get number of clashes
% All points where there was a clash, move away from each other
x(clash1) = x(clash1) + (x(clash1)-x(clash2))*dp;
x(clash2) = x(clash2) - (x(clash1)-x(clash2))*dp;
y(clash1) = y(clash1) + (y(clash1)-y(clash2))*dp;
y(clash2) = y(clash2) - (y(clash1)-y(clash2))*dp;
end
% Plot to visualise results. Colour fade from dark to bright green over time
scatter(x,y,'.','markeredgecolor',[0.1,t/time,0.4]);
drawnow;
end
hold off
结果:
编辑:
为了获得更清晰的图表,您可以初始化一些颜色矩阵 C = rand(nn,3);
并使用
绘图
scatter(x,y,[],C*(t/time),'.'); % the (t/time) factor makes it fade from dark to light
这会给每个粒子一种不同的颜色,它们也会从暗淡到亮,而不是像以前那样只是从暗到亮。结果将是这样的:
我写了一个代码来模拟二维盒子中圆形粒子的运动。每当它们离开盒子时,我都会将它们放在盒子内并靠近墙壁。我想在代码中添加粒子的直径(2R),这意味着当两个圆心之间的距离小于2R时,它们沿着连接它们中心的线分开,使得圆心之间的距离变为等于 2R。
谁能推荐一个防止粒子重叠的代码?
这是我的代码,其中不考虑重叠:
clear all
close all
l = 224; nn = 800; %number of particles
time = 1000; dd = 1;
x= l*rand(1,nn);
y= l*rand(1,nn);
for t = 1:time;
x= x + rand(1,nn)-0.5* ones(1,nn);
y=y+rand(1,nn)-0.5* ones (1,nn);
index = (x < 0); x(index) = abs(normrnd(0,1,1,nnz(index)));
index = (y < 0); y(index) = abs(normrnd(0,1,1,nnz(index)));
index = (x > l); x(index) = l-abs(normrnd(0,1,1,nnz(index)));
index = (y > l); y(index) = l-abs(normrnd(0,1,1,nnz(index)));
end
这是一些注释代码,可以满足您的需求。特别是:
psize
是一些定义的相互作用粒子大小。- 使用
pdist2
. 找到的点到点距离
- 距离太近的点将彼此远离一定量(
dp
乘以当前距离,如果dp=1/2
则它们的 x 和 y 距离加倍)直到没有冲突。
详情见评论。
clear; close all;
l = 224; nn = 800; % number of particles
time = 100;
x = l*rand(1,nn); y = l*rand(1,nn);
psize = 2; % Particle size for interaction
dp = 0.1;
figure; hold on; axis([0 l 0 l]);
for t = 1:time;
% Random movement
movement = 2*rand(2,nn)-1;
x = x + movement(1,:);
y = y + movement(2,:);
index = (x < 0); x(index) = abs(normrnd(0,1,1,nnz(index)));
index = (y < 0); y(index) = abs(normrnd(0,1,1,nnz(index)));
index = (x > l); x(index) = l-abs(normrnd(0,1,1,nnz(index)));
index = (y > l); y(index) = l-abs(normrnd(0,1,1,nnz(index)));
% Particle interaction. Loop until there are no clashes. For
% robustness, some max iteration counter should be added!
numclash = 1;
while numclash > 0
dists = pdist2([x;y]', [x;y]'); % Distances between all particles
dists(dists < psize) = NaN; % Those too close are assigned NaN
tooclose = isnan(tril(dists,-1)); % All NaNs identified by logical
[clash1,clash2] = find(tooclose); % Get particles which are clashing
numclash = numel(clash1); % Get number of clashes
% All points where there was a clash, move away from each other
x(clash1) = x(clash1) + (x(clash1)-x(clash2))*dp;
x(clash2) = x(clash2) - (x(clash1)-x(clash2))*dp;
y(clash1) = y(clash1) + (y(clash1)-y(clash2))*dp;
y(clash2) = y(clash2) - (y(clash1)-y(clash2))*dp;
end
% Plot to visualise results. Colour fade from dark to bright green over time
scatter(x,y,'.','markeredgecolor',[0.1,t/time,0.4]);
drawnow;
end
hold off
结果:
编辑:
为了获得更清晰的图表,您可以初始化一些颜色矩阵 C = rand(nn,3);
并使用
scatter(x,y,[],C*(t/time),'.'); % the (t/time) factor makes it fade from dark to light
这会给每个粒子一种不同的颜色,它们也会从暗淡到亮,而不是像以前那样只是从暗到亮。结果将是这样的: