有4个人分别站在正方形场地的4个顶点处,他们同时出发并以相同大小的、方向时刻指向下一个人的速度,顺时针方向跑动。现在需要求出他们四人的轨迹图。
前言
之前看到一个问题:4个人分别站在正方形场地的4个顶点处,他们同时出发并以相同大小的、方向时刻指向下一个人的速度,顺时针方向跑动。现在需要求出他们四人的轨迹图。刚好借此机会作为我CSDN的第一篇文章好了!
一、问题分析
这个问题的关键是,大家的速度方向时刻改变。速度改变的同时,位置也在改变。好的是,速度大小不变,所以只需要考虑速度的方向。考虑方向的问题,可以采用建坐标系的方法。方便起见,把正方形的一个点放在坐标原点。假设正方形的边长为a。那么4个人所在的位置坐标分别为(0,0),(a,0),(a,a),(0,a)。
首先假设A和B分别代表两个人t时刻的位置。其中
则此刻两点连线与x轴夹角的三角函数值分别为:
采用微元法的思想,可以把一个曲线轨迹变成很多段直线。即在一个非常小的dt时间段内,视为所有人运行路线为直线。
则t+dt时刻,A、B两个人的位置分别为:
这样就可以把一个连续的问题转化成离散的问题,用matlab求解了。
二、具体代码
1.第一个点的轨迹计算
不妨将点1取在坐标轴原点。即(0,0)点。
于是设置两个点:A(0,0),B(0,a)。A点要朝着B点运动。
%初始点为(0,0)和(a,0) x1=0;y1=0; x2=0;y2=a;
用[x1,y1]矩阵来表示A点此时刻的坐标,并将其保存在矩阵x1k中。
接下来要列出x1和y1的运算迭代式。
dis=sqrt((x2-x1)^2+(y2-y1)^2);%计算此时刻两点距离的开平方 t=t+Dt;%步进时间 x1=x1+v*Dt*(y1-x1)/dis;%计算步进时间后点1所在的横坐标,并将其加入矩阵中 x1k=[x1k,x1]; y1=y1+v*Dt*(a-x1-y1)/dis;%计算步进时间后点1所在的纵坐标,并放入矩阵中 y1k=[y1k,y1];
为什么对于x1的计算出现了(y1-x1)/dis这个代码呢?
由上一节,我们可以知道,该点下一时刻的横坐标与该点和它追击的那个点此刻夹角的余弦有关。所以我们需要得到A点追击的那个点(设为B)此时刻的横坐标。
B点此刻的横坐标怎么求呢?请看下文分析
2.对称性分析
因为四个人站在正方形的四个点,而正方形同时具有轴对称性和中心对称性,所以为了简化计算,可以引入对称性分析。
对比A和B点,A点初始坐标(0,0),朝着B点初始坐标(0,a)运动;同样地,B点初始坐标(0,a),朝着C点初始坐标(a,a)运动。这两段运动的轨迹形状应该完全一致,存在的只有方向性区别。
再分析,A点运行轨迹应该是沿着y轴,慢慢向中心卷进去的曲线。
B点运行轨迹应该是沿着x轴方向,慢慢向中心卷进去的曲线。
则在坐标系范围内,B的运行轨迹是可以由A运行轨迹顺时针旋转90°得到的。
顺时针旋转之后,B的横坐标,等于A的纵坐标,B的纵坐标等于正方形边长减去A的横坐标。代码中使用x3k和y3k分别存放B点的横纵坐标。
x3=y1;%点B可以看作点A顺时针旋转了90° x3k=[x3k,x3]; y3=a-x1; y3k=[y3k,y3];
同理,A和C点应该是完全的中心对称,D与B中心对称。所以很容易写出C、D点的轨迹矩阵。
x2=a-x1;%C点与A点是关于正方形中心对称 x2k=[x2k,x2]; y2=a-y1; y2k=[y2k,y2]; x4=a-y1; x4k=[x4k,x4]; y4=x1; y4k=[y4k,y4];
这时候,回归到上一小节遗留问题。因为顺时针旋转之后,B的横坐标,等于A的纵坐标,B的纵坐标等于正方形边长减去A的横坐标。所以代码中直接用(y1-x1)/dis来代替上一节公式分析里面的cosα。
3.代码串联
将该程序封装成一个函数。则代码如下:
function Experiment_Chase(a,v,d)
%建立一个追击函数chase,
%a是四个点相距的距离,
%v是他们运动的速度
%d是需要的采样率。
if nargin==0
a=10;
v=2;
d=0.1;
elseif isemkty(d)
d=0.1;%采样率默认设置为0.01
end
t=0;%初始化时间
%建立四个点分别的横纵坐标空集合
x1k=[];y1k=[];
x2k=[];y2k=[];
x3k=[];y3k=[];
x4k=[];y4k=[];
%初始点为(0,0)和(a,0)
x1=0;y1=0;
x2=0;y2=a;
Dt=1/(100*v);
%时间步进,速度越快,Dt越小
hold on
axis([0,a,0,a]);grid on
while(1)
dis=sqrt((x2-x1)^2+(y2-y1)^2);%计算此时刻两点距离的开平方
t=t+Dt;%步进时间
x1=x1+v*Dt*(y1-x1)/dis;%计算步进时间后点A所在的横坐标,并将其加入矩阵中
x1k=[x1k,x1];
y1=y1+v*Dt*(a-x1-y1)/dis;%计算步进时间后点A所在的纵坐标,并放入矩阵中
y1k=[y1k,y1];
x2=a-x1;%C点与A点是关于正方形中心对称
x2k=[x2k,x2];
y2=a-y1;
y2k=[y2k,y2];
x3=y1;%点B可以看作点A顺时针旋转了90°
x3k=[x3k,x3];
y3=a-x1;
y3k=[y3k,y3];
x4=a-y1;
x4k=[x4k,x4];
y4=x1;
y4k=[y4k,y4];
if dis<d
break
end
end
h=plot(x1k,y1k,'b',x2k,y2k,'r',x3k,y3k,'g',x4k,y4k,'m');
legend('点A运行轨迹','点C运行轨迹','点B运行轨迹','点D运行轨迹')%想要预先出轨迹,解开这一行;画动态图时请备注
axis square
4.画出动态轨迹
用set函数来画四个点每时每刻的位置,用line函数来将之连线,最后使用pause延迟函数和循环可以产生动态图的效果。
X=[];Y=[];
for i=2:length(x1k)
X=[x1k(i),x3k(i),x2k(i),x4k(i),x1k(i)];
Y=[y1k(i),y3k(i),y2k(i),y4k(i),y1k(i)];
set(h,'XData',X,'YData',Y,'color','k','marker','*','linesty','--');
line([x1k(i),x1k(i-1)],[y1k(i),y1k(i-1)],'color','b')%轨迹随之而动
line([x2k(i),x2k(i-1)],[y2k(i),y2k(i-1)],'color','g')
line([x3k(i),x3k(i-1)],[y3k(i),y3k(i-1)],'color','r')
line([x4k(i),x4k(i-1)],[y4k(i),y4k(i-1)],'color','m')
pause(0.001)
end
总结
以上就是今天要讲的内容,本文简单地使用了化连续为离散的思想,这种思想在matlab使用中有很大用处;本文使用的对称性分析在一些特殊问题的分析上有很大优势;最后由借助set函数和pause函数配合画出了动态图。
限于笔者能力有限,且确实是第一次写博客,内容难免有不当之处,还请诸君斧正。