在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

这会给每个粒子一种不同的颜色,它们也会从暗淡到亮,而不是像以前那样只是从暗到亮。结果将是这样的: