2015-05-03 56 views
0

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

这是我到目前为止有:

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

请张贴一些代码,并显示你到目前为止。你有什么试图解决这个问题?基于角度,坐标(x,y)是否以可预测的方式变化?这可以帮助调试。 – ohruunuruus

+0

我只有在de点到达半径为500的点时做了某些事情的验证。我使用x,y使用了点的maginitude,但我不知道如何改变角度以保持点circule – user3312370

+0

我试图生成randon值* pi,然后用它来计算新的x,y为新的角度,但这不起作用 – user3312370

回答

1

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

新的角度计算的方式

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

新角度的计算的一种可能的解决方案是增加为“angulo”:

PI(180°)只是扭转轨迹

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

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

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

建议的解决方案已在下面的代码中实现。

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

此外,一些冗余/不必要的代码行也被评论过。

某些功能也已被添加:

轨迹标记可在的函数的结束是或者是情节“交互式”(在每个 iteratiion“)或全部一起

绘图。脚本结尾处的轨迹使脚本更快(当然),在约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

希望这有助于。