Matlab 使粒子在圆内随机移动

Matlab 使粒子在圆内随机移动,matlab,animation,matlab-figure,simulate,Matlab,Animation,Matlab Figure,Simulate,我试图使绘制的点在已知半径和中心的圆内移动。目前我可以在边界内生成点,但现在我需要使它们移动 我有以下脚本来生成粒子的初始位置 function [particle_gen] = generate(n,centre,radius) %generates n particles in a circle with specified centre and radius angle = 2 * pi * rand(n,1); r = radius * sqrt(rand(n,

我试图使绘制的点在已知半径和中心的圆内移动。目前我可以在边界内生成点,但现在我需要使它们移动

我有以下脚本来生成粒子的初始位置

function [particle_gen] = generate(n,centre,radius)
    %generates n particles in a circle with specified centre and radius

    angle = 2 * pi * rand(n,1);
    r = radius * sqrt(rand(n,1));
    X = r.*cos(angle) + centre(1);
    Y = r.*sin(angle) + centre(2);
    plot(X,Y,'.k')
end

我想给它们设置动画,使粒子以恒定速度沿直线移动,直到它们碰到圆形边界并反弹。我需要这一切都发生在同一个绘图中。

这不是一个小问题。您当前的方法为您提供初始起始位置。您还需要生成起始“速度”,我将其称为VX和VY

也就是说,存储X、Y位置阵列以及VX和VY方向阵列,其中VX和VY的每一条“线”都有一个常数范数。然后,您将在每次迭代中通过相应的VX和VY来增加每个位置X、Y,然后检查您是否靠墙,然后更改VX和VY,以使撞击墙的点“反弹”离开墙


希望这能让你开始!祝你好运。

好的,这个问题有几个方面,我将分别讨论

更新打印对象 至于创建绘图和更新绘图值的逻辑,您可以使用。如果创建打印对象,可以使用到打印的来更新打印

plt = plot(x, y, 'k.');
set(plt, 'XData', newx, 'YData', newy)
在您的例子中,newx和newy值将在循环中计算,然后您可以分配它们。通过这样做,您将不会不断地创建新的图形对象,因为使用MATLAB可能会非常昂贵

由于要进行大量计算,因此还需要使用每次循环来强制MATLAB渲染图形

粒子轨迹 您将需要计算要用以更新绘图的xnew和ynew值。有很多方法可以确定这些轨迹,但我在这里介绍了一种方法

应用置换。使用“速度”和“方向”,可以将置换应用于每个粒子。 确定点是否在圆的外部。如果位移把点放在圆的基本方程之外,那么我们需要把它放回圆中。如果圆外没有点,则返回步骤1。 对于圆外的每个点,找到其路径与圆的交点。这是一个非常简单的练习,用作参考。 在此点找到圆的切线。同样,这很简单,因为我们可以从圆的中心到圆的交点画一条线。该直线斜率的负倒数是切线在交点处与曲线的斜率。通过结合交点,我们得到了一条直线的方程。 通过此切线反射圆外部的点,以将其反弹回圆中。点在直线上的这种反射可以使用。 示例解 我已经实施了上述步骤。虽然这可能不是计算效率最高的方法,但它提供了期望的结果

function bounce(npts, vmin, vmax, radius, center)

    % Initial direction/velocity of the points
    direction = rand(npts, 1) * 2 *pi;
    velocity = (rand(npts, 1) * (vmax - vmin)) + vmin;

    % Create random starting locations within the circle
    theta = rand(npts, 1) * 2*pi;
    r = radius * sqrt(rand(npts, 1));

    XY = [r .* cos(theta(:)) + center(1), ...
          r .* sin(theta(:)) + center(2)];

    % Initial plot objects
    hfig = figure('Color', 'w');
    hax = axes('Parent', hfig);

    % Plot the dots as black markers
    hdots = plot(XY(:,1), XY(:,2), ...
                'Parent', hax, ...
                'Marker', '.', ...
                'Color', 'k', ...
                'LineStyle', 'none', ...
                'MarkerSize', 12);

    hold(hax, 'on')
    axis(hax, 'equal')

    % Plot the circle as a reference
    t = linspace(0, 2*pi, 100);
    plot(radius * cos(t) + center(1), ...
         radius * sin(t) + center(2))

    % Keep simulating until we actually close the window
    while ishghandle(hfig);
        % Determine new dot locations
        [XY, direction] = step(XY, direction, velocity, radius, center);

        % Update the dot plot to reflect new locations
        set(hdots, 'XData', XY(:,1), 'YData', XY(:,2))

        % Force a redraw
        drawnow
    end
end

function [XYnew, direction] = step(XY, direction, velocity, radius, center)
    % Compute the next position of the points
    DX = [cos(direction(:)) .* velocity, ...
          sin(direction(:)) .* velocity];
    XYnew = XY + DX;

    % Now check that they are all inside circle
    isOutside = sum(bsxfun(@minus, XYnew, center).^2, 2) > radius^2;

    % The ones that are outside should "bounce" back into the circle
    if any(isOutside)        
        orig  = XY(isOutside,:);
        new   = XYnew(isOutside,:);
        delta = -DX(isOutside,:);

        % Find intersection of this path with the circle
        % Taken from: https://math.stackexchange.com/a/311956
        a = sum(delta.^2, 2);
        b = sum(2 .* delta .* bsxfun(@minus, orig, center), 2);
        c = sum(bsxfun(@minus, orig, center).^2, 2) - radius^2;

        t = (2 * c) ./ (-b + sqrt(b.^2 - 4 .* a .* c)); 
        xintersect = orig(:,1) + delta(:,1) .* t;
        yintersect = orig(:,2) + delta(:,2) .* t;

        % Get tangent at this intersection (slope/intercept form)
        m = - 1 ./ ((yintersect - center(2)) ./ (xintersect - center(1)));
        b = yintersect - m .* xintersect;

        % "Reflect" outside points across the tangent line to "bounce" them
        % Equations from: https://stackoverflow.com/a/3307181/670206
        d = (new(:,1) + (new(:,2) - b) .* m) ./ (1 + m.^2);

        XYnew(isOutside,1) = 2 * d - new(:,1);
        XYnew(isOutside,2) = 2 .* d .* m - new(:,2) + 2 .* b;

        % Recompute the direction of the particles that "bounced"
        direction(isOutside) = atan2(XYnew(isOutside,2) - yintersect, ...
                                     XYnew(isOutside,1) - xintersect);
    end
end
结果 通过运行以下命令,我能够获得以下结果

bounce(100, 0.01, 0.2, 5, [0 0]);

边界圆也是用一个简单的圆函数生成的,我不知道你的问题是什么。你能试着描述一下你想要改善的行为吗?你是否想要第二个图,其中每个点都在一个随机方向上移动了一小段随机距离?如果它们移动到边界之外,你希望发生什么?它们必须像普通粒子一样移动,直线运动,直到碰到墙壁,它们就会反弹。它也必须在同一个情节中。@Vladamir,你的评论非常重要!请下次在问题中包含该信息!:我忘了提到,粒子之间会产生库仑式的排斥力;回答得好!很酷。我只是希望你没有为他们做OP的家庭作业@安德拉斯蒂克,坚持下去,我们将以。@chessofnerd或: