Matlab中的随机方向

时间:2015-05-03 06:42:02

标签: matlab

我在matlab编程。一个点使用随机方向移动到圆圈中。当该点达到该区域的极限时,该点必须在0-180之间改变其角度。当点达到极限时我能找到。但我不知道如何改变角度并继续这个过程,因为当我改变角度时,点出现在另一个坐标(x,y) - 我不希望这样。当该点达到位置(x,y)的极限时,我想改变角度并使该点从(x,y)继续。

这是我到目前为止所拥有的:

function [ X ] = random_direction( )
    bs = rsmak('circle',500,[0 0]);
    fnplt(bs,'b'), axis square;
    hold on
    magnitud=0;
    x=0;
    y=0;

    base_station(1:10)=struct('id',0,'position_x',0, 'position_y',0);
    dis=rand()*500;
    angulo=2*pi*rand();
    base_station(1).position_x =dis*cos(angulo);
    base_station(1).position_y =dis*sin(angulo);
    bandera=0;

    for i=1:100

        magnitud = sqrt(base_station(1).position_x^2+base_station(1).position_y^2);
        angulo=atan(base_station(1).position_y/base_station(1).position_x);

        if magnitud >= 500
            if bandera==0
                angulo=2*pi*rand();
            end
            x=10 * cos(angulo);  
            y=10 * sin(angulo);

            base_station(1).position_x= base_station(1).position_x+x;
            base_station(1).position_y=base_station(1).position_y+y;                           
            bandera=1;
        end

        if magnitud <500 && bandera==0
            base_station(1).position_x= base_station(1).position_x+10;
            base_station(1).position_y=base_station(1).position_y+10;
        end

        bs = rsmak('circle',10,[base_station(1).position_x base_station(1).position_y ]);
        fnplt(bs,'g'), axis square;
    end
end 

1 个答案:

答案 0 :(得分:1)

正如已经提供的一些评论所指出的,两个主要问题是:

计算新角度的方式

“if”块“if magnitud <500 && bandera==0”中的错误,其中“x”和“y”未分别乘以cos(angulo)sin(angulo)

计算新角度的可能解决方案是添加到“angulo”:

  

pi(180°)只是为了扭转轨迹

     

随机角度偏移以区分新轨迹与   前一个避免沿着同一条线上下移动)

角度偏移定义为固定角度与“-0.5 and 0.5”之间随机数的乘积。

当计算新角度时,进行有效性检查以验证新轨迹是否将“退出”圆圈。如果是这样,偏移角度的符号会改变。

建议的解决方案已在随后的代码中实现。

在代码中,修改后的原始代码行已经“注释”为“%%%”(3%)。

此外,还注释了一些冗余/不必要的代码行。

还添加了一些功能:

  

轨迹标记可以是“交互式”的图(每个都是   迭代“)或在函数末尾一起。

     

在脚本末尾绘制轨迹使脚本更快(当然),在大约1.5秒内计算30000次迭代

     

轨迹点存储在“X”输出变量

中      

迭代次数由参数

定义

脚本中的注释应该澄清修改。

该脚本已经过多达30000次迭代测试。

function [ X ] = random_direction( )
% updated plot of the circle
%%%bs = rsmak('circle',500,[0 0]);
%%%fnplt(bs,'b'), axis square;
plot([cos([0:.01:2*pi])*500],[sin([0:.01:2*pi])*500],'b')
hold on
daspect([1 1 1])
set(gca,'xlim',[-600 600],'ylim',[-600 600])
grid on

magnitud=0;
x=0;
y=0;

% added interactive plot mode flag:
% interactive=1 plots a mark at each iteraton
% interactive=0 plots the whole trajectory at the end of the run
%               trajectory points are also stored in the X output
%               variable
interactive=0;
% added setting of the number of iterations
n_iterations=30000;
X=zeros(n_iterations,2);

% location from 2 to 10 are not used
base_station(1:10)=struct('id',0,'position_x',0, 'position_y',0);
dis=rand()*500;
angulo=2*pi*rand();
base_station(1).position_x =dis*cos(angulo);
base_station(1).position_y =dis*sin(angulo);
bandera=0;
% off_angle is used when the point has to invert its direction. its
% value is multiplied by (rand_numb -0.5). The desired effect is to
% avoid the point just comes back in the opposite direction
off_angle=120*pi/180;

for i=1:n_iterations

    magnitud = sqrt(base_station(1).position_x^2+base_station(1).position_y^2);
    % added reset of bandera if magnitud < 500
    if(magnitud < 500)
       bandera=0;
    end
    % angulo changes only when magnitud is >= 500, so it does not need
    % to be calculated at each iteration
    %%%angulo=atan(base_station(1).position_y/base_station(1).position_x);

    if magnitud >= 500
        if bandera==0
            % updated computation of the new angulo
            %%%angulo=2*pi*rand();
            n_rand=rand();
            rand_off_angle=off_angle*(n_rand - 0.5);
            % added check for new angle validity
            tmp_x=base_station(1).position_x + 10*3 * cos(angulo + pi + rand_off_angle);
            tmp_y=base_station(1).position_y + 10*3 * sin(angulo + pi + rand_off_angle);
            tmp_d=sqrt(tmp_x^2+tmp_y^2);
            if(tmp_d > 500)
               rand_off_angle= - rand_off_angle;
            end
            angulo=angulo + pi + rand_off_angle;
            % added check for new angle > 360°
            if(angulo > 2*pi)
               angulo=angulo-2*pi;
            end
        end
        x=10 * cos(angulo);  
        y=10 * sin(angulo);

        base_station(1).position_x= base_station(1).position_x+x;
        base_station(1).position_y=base_station(1).position_y+y;                           
        bandera=1;
    end

    if magnitud <500 && bandera==0
        % positions are respectively multiplied by cos(angulo) and
        % sin(angulo)
        %%%base_station(1).position_x= base_station(1).position_x+10;
        %%%base_station(1).position_y=base_station(1).position_y+10;
        base_station(1).position_x= base_station(1).position_x + 10 * cos(angulo);
        base_station(1).position_y=base_station(1).position_y + 10  * sin(angulo);
    end

    % not neede to re-plot the circle at each iteration
    %%%bs = rsmak('circle',10,[base_station(1).position_x base_station(1).position_y ]);
    %%%fnplt(bs,'g'), axis square;
    % check for interactive plot
    if(interactive)
       plot(base_station(1).position_x , base_station(1).position_y,'xr') 
       pause(0.001);
    end
    % added storing of trajectory points
    X(i,1)=base_station(1).position_x;
    X(i,2)=base_station(1).position_y;
    % added "pause" command just to slow down the plot
end
% added plot of trajectory if not interactive has not been selected
if(~interactive)
   plot(X(:,1),X(:,2),'r')
end
end

以下图像显示了以下结果:300,3000,10000和30000次迭代。

300 Iterations

3000 Iterations

10000 Iterations

30000 Iterations

希望这有帮助。