【问题标题】:Simulating random walkers which can not collide into each other in Matlab在 Matlab 中模拟不能相互碰撞的随机步行者
【发布时间】:2017-10-24 13:22:03
【问题描述】:

我编写了一个代码来模拟二维盒子中圆形粒子的运动。每当他们搬出盒子时,我都会把它们放在盒子里靠近墙壁的地方。我想在代码中添加粒子的直径(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

【问题讨论】:

  • 所以每个粒子都沿直线行进,直到它与墙壁接触,当它“反弹”时,您还想包括粒子间的碰撞吗?
  • 随着时间的推移,每一步的方向和长度步长没有变化(我使用随机数来做到这一点)。是的,当两个圆的中心之间的距离小于 2R 时,它们会沿着连接它们的中心和圆心距离的线等于@Wolfie
  • 你能帮忙吗? @Wolfie
  • 3 个或更多粒子同时碰撞(可能不太可能)会发生什么?
  • 你看到的问题叫做Collision Detection

标签: matlab random collision-detection simulation


【解决方案1】:

这是一些注释代码,可以满足您的需求。值得注意的是:

  • psize 是一些为相互作用而定义的粒子大小。
  • 使用pdist2 找到的点到点距离。
  • 距离太近的点会彼此远离一定距离(dp 乘以它们当前的距离,如果dp=1/2 则它们的 x 和 y 距离加倍)直到没有冲突。

详见 cmets。

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

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

【讨论】:

  • 我无法理解冲突 1 和冲突 2 之间的区别
  • clash1 中的每个粒子与clash2 中的相应粒子碰撞。我不知道,请提供一个例子,也许粒子是正确大小的圆圈,这样你就可以清楚地看到它们是否真的在碰撞。如果此答案有效,请将其标记为已接受。
  • 当5个或8个粒子碰撞在一起时代码是否正常工作?
  • 我还没有完全测试过这段代码,但它的工作方式(如前所述)是在移动到下一次迭代之前不断移动粒子直到没有重叠,所以是的,它应该可以工作.它可能看起来不像是因为您使用的粒子数量众多、网格的大小以及散点大小与您定义的点大小不匹配的事实psize
  • 我没有这样做,因为代码中存在一个问题:考虑创建大量粒子的情况。在这种情况下,最好让粒子远离质量,但在代码中不考虑它。我说的对吗?
猜你喜欢
  • 2013-04-24
  • 1970-01-01
  • 2019-03-27
  • 2023-03-16
  • 2019-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多