2017-05-24 44 views
1

我已經編寫了一個代碼來模擬2d框中的圓形顆粒的運動。每當他們從箱子中移出時,我都把它們放在箱子裏面,靠近牆壁。我想在代碼中添加粒子的直徑(2R),這意味着當兩個圓的中心之間的距離變得小於2R時,它們沿着連接它們中心的直線分開,這樣圓的中心之間的距離變成等於2R。模擬在Matlab中不能碰撞到彼此的隨機步行者

任何人都可以提出一個代碼,以防止重疊的粒子?

這是我的代碼在重疊不考慮:

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 
+0

所以每個粒子行進在一條直線上,直到它與牆壁接觸,當「反彈」,並且要還包括顆粒的粒子碰撞? – Wolfie

+0

每一步的方向和長度都沒有變化(我用隨機數來做)。當兩個圓的中心之間的距離變得小於2R時,它們沿着連接它們中心和距離的線分開的圓心等於@Wolfie –

+0

你能幫忙嗎? @Wolfie –

回答

2

下面是一些註釋代碼,你想要做什麼。值得注意的是:

  • psize是一些定義的相互作用的粒徑。
  • 使用pdist2找到的點對點距離。
  • 太接近的點彼此相距一定距離(如果dp=1/2那麼它們的x和y距離加倍),直到沒有衝突爲止(dp乘以它們的當前距離)。

查看註釋瞭解詳情。

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 

結果:

random walk


編輯:

更清晰的圖,你可以使用初始化

scatter(x,y,[],C*(t/time),'.'); % the (t/time) factor makes it fade from dark to light 
一些彩色矩陣 C = rand(nn,3);和情節

這會給每個粒子一個不同的顏色,它也會從黑暗到淡淡,而不是像從前一樣從黑暗到淡淡。其結果將是這樣的:

colours

+0

我不能在clash1和clash2 –

+0

'clash1'中的每個粒子都與'clash2'中的相應粒子發生碰撞。我不知道,請舉個例子,也許粒子的大小是正確的,因此你可以清楚地看到它們是否實際發生碰撞。如果此答案有效,請將其標記爲已接受。 – Wolfie

+0

當5個或8個粒子碰撞togheter時代碼是否正常工作? –