猎狗与兔子问题的Matlab编程思路与过程

猎狗与兔子问题

有一只雄狗在B点位置发现了一只兔子在正东北方距离它200米的地方O处。此时免子开始以 8m/s的速度向正西北万亞离为 120 m 的洞口 A 全速跑去,假设猎狗在追赶兔子的时候始终朝着免于的方向全速奔跑,按要求完成下面的实验:
(1)问猎狗能追上兔子的最小速度是多少,
(2)选取猎狗的速度分别为 15m/s,18 m/s,计算猎狗追赶免子时跑过的路程。
(3)画出猎狗追赶兔子奔跑的曲线图.

问题(1)分解

问题的整体结构

  由于我们是要求得猎狗能够抓到兔子的最小速度,所以我们应当设置一个大循环,在这个循环中,我们不断增加猎狗的初始速度。然后,在增加了猎狗的初始速度后,再进入一个小循环,用来计算猎狗是否能够抓到兔子。如果不能抓到兔子,小循环便自动结束,返回到大循环并进入下一轮循环;如果能够抓住兔子,便结束小循环并同时结束大循环,并输出猎狗的初始速度。其流程图如下:
在这里插入图片描述

猎狗与兔子的初始位置

上面的问题本质上是一个二维平面上的几何问题,所以我们先建立一个坐标系。因为问题的描述中是以猎狗所在的B点来描述位置关系的,所以我们就以猎狗所在的初始位置来作为坐标系的原点,同时将坐标系的正上方作为正北、正右方作为正东。
由此,我们可以初步的建立一个初始状态的二维平面状态图:
在这里插入图片描述

兔子的移动

  要求解问题,我们需要不断的按照时间进行迭代计算猎狗和兔子的最新位置,并进行“猎狗——兔子”、“兔子——洞口”的关系判断。
  首先,我们设置一个变量Tstep,用于表示每一轮迭代的计算时间。然后,设置变量rabSpeed和dogSpeed用于表示兔子和猎狗各自的速度。然后用rab(1,1)和rab(1,2)分别存储兔子每一轮迭代的坐标X、Y值;并用dog(1,1)和dog(1,2)分别存储猎狗每一轮迭代的坐标X、Y值。
  对于兔子来说,显然它的初始位置X值为sin(45°)*200、Y值也是sin(45°)*200。故有:

rab(1,1)=200/sqrt(2); 
rab(1,2)=200/sqrt(2);

  对于兔子来说,每一轮迭代它都会跑TsteprabSpeed的距离。而因为兔子是向正西北方向逃跑,所以显然在每一轮迭代里兔子的X坐标会减小TsteprabSpeedsin(45°),兔子的Y坐标会增加TsteprabSpeed*sin(45°)。故有:

rab(1,1)=rab(1,1)-(Tstep*rabSpeed/sqrt(2));
rab(1,2)=rab(1,2)+(Tstep*rabSpeed/sqrt(2));

  

兔子逃跑成功的判断

  由初始位置图可以得知,兔子从自己的起始位置不断的向洞口方向进行靠近。当兔子进入洞口后,兔子的X坐标将小于等于洞口位置的X坐标。所以,只要兔子的X坐标小于等于洞口的X坐标后,我们就可以认为兔子逃跑成功,便可以直接终止迭代计算了。即:

if rab(1,1)<=200/sqrt(2)-120/sqrt(2);
    break; 
end

猎狗的移动

  猎狗的移动的基本思路与兔子相同,但是猎狗在移动的时候移动方向始终是朝向兔子的。猎狗的移动可以用下面的图来表示:
在这里插入图片描述

  其中,A为兔子和猎狗的X坐标的的差值,B为兔子和猎狗的Y坐标的差值,a为猎狗在当前一轮迭代中X方向的移动距离,b为猎狗在当前一轮迭代中Y方向的移动距离,s则为猎狗在本轮迭代中的移动距离,S为猎狗在本轮迭代中的初始位置和兔子位置间的距离。
  显然有a/s=A/S、b/s=B/S,即a=A * s/S、b=B * s/S。
由上,我们可以获得猎狗的移动程序段为:

	x=rab(1,1)-dog(1,1); %对应上图中的A
    y=rab(1,2)-dog(1,2); %对应上图中的B
    xy=sqrt(x^2+y^2);    %对应上图中的S
    dog(1,1)=dog(1,1)+x/xy*(dogSpeed*Tstep);  %dogSpeed*Tstep为猎狗一轮迭代中的移动距离
										      %对应上图中的s
    dog(1,2)=dog(1,2)+y/xy*(dogSpeed*Tstep);

猎狗抓到兔子的判断

  对于猎狗来说,只要在某一轮迭代中,它(在位置更新前)与兔子(位置更新后)之间的距离小于等于猎狗所跑的距离,就说明在本轮迭代中猎狗会捕获到兔子。即判断条件为

(猎狗x-兔子x)^ 2   +(猎狗y-兔子y)^2 < 猎狗速度 * 迭代时间  

  用Matlab代码表示为:

 if (dog(1,1)-rab(1,1))^2+(dog(1,2)-rab(1,2))^2<=(dogSpeed*Tstep)^2
       flag=1;   %flag用来标识猎狗是否已抓到兔子
       break;
 end

问题的总体代码

  我们把各个计算和判断的部分根据流程图进行组合,得到问题(1)的整体代码如下:

 
clear
clc
Tstep=0.01;
rabSpeed=8;
dogSpeed=7;
flag=0;
tar=200/sqrt(2)-120/sqrt(2);
while 1
    dogSpeed=dogSpeed+0.1;
    rab(1,1)=200/sqrt(2);
    rab(1,2)=200/sqrt(2);
    dog(1,1)=0;
    dog(1,2)=0;
    while 1
        rab(1,1)=rab(1,1)-(Tstep*rabSpeed/sqrt(2));
        rab(1,2)=rab(1,2)+(Tstep*rabSpeed/sqrt(2));
        if rab(1,1)<=tar
           break; 
        end
        if (dog(1,1)-rab(1,1))^2+(dog(1,2)-rab(1,2))^2<=(dogSpeed*Tstep)^2
           flag=1;
           break;
        end
        x=rab(1,1)-dog(1,1);
        y=rab(1,2)-dog(1,2);
        xy=sqrt(x^2+y^2);
        dog(1,1)=dog(1,1)+x/xy*(dogSpeed*Tstep);
        dog(1,2)=dog(1,2)+y/xy*(dogSpeed*Tstep);
    end
    if flag==1
       break; 
    end
end
disp('最小速度是:');
disp(dogSpeed);

  代码的运行结果:

问题(2)(3)的求解

  问题(2)(3)实际上可以看作是同一个问题的不同过程量的展示,所以在此作为一个问题进行求解。而问题(2)(3)的基本构架与问题(1)是相同的,区别在于——1、不需要外层的大循环来进行最小速度的叠加;2、需要对每次迭代猎狗所跑的距离进行叠加;3、需要存储猎狗和兔子每轮迭代中的位置,并最终画出曲线。
  对于1,我们只需要直接删除外层的大循环;对于2,我们可以设置一个变量S并在每次迭代中向其累加猎狗奔跑的距离;对于3,我们引入一个计数器c,用于存储迭代的次数,然后将每次迭代的猎狗和兔子的位置存储到dog和rab里,最终用plot将其显示。修改后的程序如下:

	Tstep=0.01;
	rabSpeed=8;
	dogSpeed=15;
	flag=0;
	tar=200/sqrt(2)-120/sqrt(2);
    rab(1,1)=200/sqrt(2);
    rab(1,2)=200/sqrt(2);
    dog(1,1)=0;
    dog(1,2)=0;
    c=1; %计数器,用来标识迭代次数
    S=0;
    while 1
        rab(c+1,1)=rab(c,1)-(Tstep*rabSpeed/sqrt(2));
        rab(c+1,2)=rab(c,2)+(Tstep*rabSpeed/sqrt(2));
        if rab(c+1,1)<=tar
           break; 
        end
        if (dog(c,1)-rab(c+1,1))^2+(dog(c,2)-rab(c+1,2))^2<=(dogSpeed*Tstep)^2
           dog(c+1,1)=rab(c+1,1);
           dog(c+1,2)=rab(c+1,2);
           S=S+sqrt((dog(c,1)-rab(c+1,1))^2+(dog(c,2)-rab(c+1,2))^2); %对猎狗跑的距离进行累加(猎狗抓到兔子的迭代中,猎狗跑的距离是猎狗和兔子间的距离)
           break;
        end
        x=rab(c+1,1)-dog(c,1);
        y=rab(c+1,2)-dog(c,2);
        xy=sqrt(x^2+y^2);
        S=S+dogSpeed*Tstep; %对猎狗跑的距离进行累加
        dog(c+1,1)=dog(c,1)+x/xy*(dogSpeed*Tstep);
        dog(c+1,2)=dog(c,2)+y/xy*(dogSpeed*Tstep);
        c=c+1;
    end
disp('猎狗奔跑距离是');
disp(S);
plot(dog(:,1),dog(:,2));
hold on;
plot(rab(:,1),rab(:,2));
 

运行结果15m/s(显然可怜的猎狗没有抓到兔子):
在这里插入图片描述
在这里插入图片描述
运行结果18m/s(显然可怜的兔子被猎狗抓到了):
在这里插入图片描述
在这里插入图片描述

  • 13
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

soar3033

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值