我在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
答案 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次迭代。
希望这有帮助。