• 自动驾驶算法岗笔试题 | 一道有意思的数学题 | 解析及代码实现


    参考资料

    这两天参加了深圳一家企业的线下笔试,这个公司出了一道当时觉得挺有意思的数学题,于是回学校后网上搜了下发现有类似的题,所以在这边总结一下。

    1. 题目描述

    3辆飞船A、B、C初始位置分别处于一个边长为 L L L的等边三角形的顶点上,即A点坐标为 ( 3 2 L , 0 ) (\frac{\sqrt{3}}{2}L,0) (23 L,0),B点坐标为 ( L 2 , 0 ) (\frac{L}{2},0) (2L,0),C点坐标为 ( − L 2 , 0 ) (-\frac{L}{2},0) (2L,0)。飞船飞行过程中,飞船均具有相等的速度 v v v,并且A始终朝着B前进,B始终朝着C前进,C始终朝着A前进。

    • 问题1:从初始到 t 1 t_1 t1时刻,飞船A,B,C的运行轨迹(假设采样时间为 Δ t \Delta t Δt)。
    • 问题2:到无穷远时刻时,飞船A,B,C最终的状态是怎样的?如果三者速度不相等,那么此时飞船A,B,C最终的状态又是怎样的?请推到分析。

    2. 问题分析

    1. 问题 1

    对于问题1,当时错误理解成A、B、C在一开始的等边三角形的边上运动了,所以三下五除二就写出来了,很快啊(真的笑哭)。。

    分析

    由题意可知,三辆飞船因为速度相等,所以每时每刻飞船之间的距离都是相等的,即每时每刻都构成一个等边三角形,大致如图所示,他们依据某种螺旋曲线靠近。

    我们从飞船A开始推导,其他两只飞船同理。假设 t t t时刻飞船A的坐标为 P A ( t ) P_A(t) PA(t),那么根据向量的关系,很容易得到下一时刻飞船A的位置 为
    P A ( t + 1 ) = P A ( t ) + n A B ( t ) v Δ t (1) \tag{1} P_A(t+1)=P_A(t)+n_{AB}(t)v\Delta t PA(t+1)=PA(t)+nAB(t)vΔt(1)

    n A B ( t ) n_{AB}(t) nAB(t) t t t时刻,飞船 A A A指向飞船 B B B的单位向量,它等于
    n A B ( t ) = P B ( t ) − P A ( t ) ∣ ∣ P B ( t ) − P A ( t ) ∣ ∣ (2) \tag{2} n_{AB}(t)=\frac{P_B(t)-P_A(t)}{||P_B(t)-P_A(t)||} nAB(t)=∣∣PB(t)PA(t)∣∣PB(t)PA(t)(2)
    将等式(2)带入等式(1),可得飞船A飞行的实时轨迹为
    P A ( t + 1 ) = P A ( t ) + P B ( t ) − P A ( t ) ∣ ∣ P B ( t ) − P A ( t ) ∣ ∣ v Δ t (3) \tag{3} P_A(t+1)=P_A(t)+\frac{P_B(t)-P_A(t)}{||P_B(t)-P_A(t)||}v\Delta t PA(t+1)=PA(t)+∣∣PB(t)PA(t)∣∣PB(t)PA(t)vΔt(3)
    同理,B、C飞船的轨迹为
    P B ( t + 1 ) = P B ( t ) + P C ( t ) − P B ( t ) ∣ ∣ P C ( t ) − P B ( t ) ∣ ∣ v Δ t (4) \tag{4} P_B(t+1)=P_B(t)+\frac{P_C(t)-P_B(t)}{||P_C(t)-P_B(t)||}v\Delta t PB(t+1)=PB(t)+∣∣PC(t)PB(t)∣∣PC(t)PB(t)vΔt(4)
    P C ( t + 1 ) = P C ( t ) + P A ( t ) − P C ( t ) ∣ ∣ P A ( t ) − P C ( t ) ∣ ∣ v Δ t (5) \tag{5} P_C(t+1)=P_C(t)+\frac{P_A(t)-P_C(t)}{||P_A(t)-P_C(t)||}v\Delta t PC(t+1)=PC(t)+∣∣PA(t)PC(t)∣∣PA(t)PC(t)vΔt(5)

    根据 等式(3)-(5),通过不停地迭代,即可求出从0时刻到 t 1 t_1 t1时刻的完整轨迹。

    python代码实现

    为了更好地画图展示效果,这边使用python编程。代码仓库见于github链接

    • 导入相关库

      import numpy as np
      import matplotlib.pyplot as plt
      from celluloid import Camera  # 保存动图时用,pip install celluloid
      
      %matplotlib qt5
      
    • 参数设置

      # 采样时间
      dt=0.01
      # 原等边三角形长度
      L=1
      # 初始坐标点
      p_a = np.array([0,np.sqrt(3)/2*L])
      p_b = np.array([1/2*L,0])
      p_c = np.array([-1/2*L,0])
      # 速度
      v_a = 1.0
      v_b = 1.0
      v_c = 1.0
      
      
      
      p_center=np.array([0,1/np.sqrt(3)/2]) # 等边三角形中心
      
      # 存储轨迹
      trajectory_a=[]
      trajectory_b=[]
      trajectory_c=[]
      
      # 假设到t时刻停止
      t = 1
      
      
      
    • 迭代公式

      def trajectory_point(p_1,p_2,v):
          n_ = (p_2-p_1)/np.linalg.norm(p_2-p_1)
          p_now = p_1+n_*v*dt
          return p_now
      
    • 求解轨迹

      def all_trajectory(p_1,p_2,p_3,v_a,v_b,v_c):
          delta=0
          while(delta<t/dt):
              p__1=trajectory_point(p_1,p_2,v_a)
              p__2=trajectory_point(p_2,p_3,v_b)
              p__3=trajectory_point(p_3,p_1,v_c)
              delta+=1
              p_1,p_2,p_3=p__1,p__2,p__3
              trajectory_a.append(p_1)
              trajectory_b.append(p_2)
              trajectory_c.append(p_3)
          return p__1,p__2,p__3
      
      
      all_trajectory(p_a,p_b,p_c,v_a,v_b,v_c)
      
      trajectory_a=np.array(trajectory_a)
      trajectory_b=np.array(trajectory_b)
      trajectory_c=np.array(trajectory_c)
      
    • 画图

      fig = plt.figure()
      camera = Camera(fig)  # 保存动图用
      for i in range(len(trajectory_a)):
          plt.cla()
      
          plt.plot([p_a[0], p_b[0]], [p_a[1], p_b[1]], '-.r', linewidth=1.0)
          plt.plot([p_b[0], p_c[0]], [p_b[1], p_c[1]], '-.r', linewidth=1.0)
          plt.plot([p_c[0], p_a[0]], [p_c[1], p_a[1]], '-.r', linewidth=1.0)
          plt.scatter(p_center[0],p_center[1])
          plt.plot(trajectory_a[0:i,0], trajectory_a[0:i,1], '-r',label="A")
          plt.plot(trajectory_b[0:i,0],trajectory_b[0:i,1],'-g',label="B")
          plt.plot(trajectory_c[0:i,0], trajectory_c[0:i,1], '-b',label="C")
          plt.legend()
          plt.xlabel('x/m')
          plt.ylabel('y/m')
          plt.axis('square')
          plt.grid(True)
          plt.pause(0.001)
          # camera.snap()
      
      
      # animation = camera.animate()
      # animation.save('trajectory.gif')
      
      plt.show()	
      

    运行轨迹如图所示:
    在这里插入图片描述

    2. 问题 2-1

    其实我们可以很容易猜到,三辆飞船在速度相等的情况下,一定会在经过一段时间后三艘飞船相遇在原等边三角形的中心处,因为他们是高度对称的。那么是在什么时候相遇呢,可以看下面推导。

    解法 1

    根据题意,由于三个飞船都作等速率曲线运动, 而任一时刻 三艘飞船的位置都在正三角形的三个顶点上, 但这三角形的边长不断缩小, 如图所示。

    现把从开始到追上的时间 t t t 分成 n n n 个相等的时间间隔 Δ t \Delta t Δt, 在每个微小的时间间隔内, 每艘飞船的运动都可看成是直线运动. 经 Δ t , 2 Δ t , 3 Δ t , ⋯ ⋯ n Δ t \Delta t, 2 \Delta t, 3 \Delta t, \cdots \cdots n \Delta t Δt,t,t,⋯⋯nΔt, 对应 的三角形边长依次为 L 1 , L 2 , L 3 ⋯ ⋯ L n L_1, L_2, L_3 \cdots \cdots L_n L1,L2,L3⋯⋯Ln。当 L n → 0 L_n \rightarrow 0 Ln0 时三艘飞船相聚。

    A 1 B 1 A_1 B_1 A1B1 A 1 B 1 ′ A_1 B_1^{\prime} A1B1,差为二阶小量, 所以
    L 1 = A 1 B 1 ≈ A 1 B 1 ′ = L − A A 1 − B B 1 cos ⁡ 6 0 ∘ = L − 3 2 v Δ t L_1=A_1 B_1\approx A_1 B_1^{\prime}=L-A A_1-B B_1 \cos 60^{\circ}=L-\frac{3}{2} v \Delta t L1=A1B1A1B1=LAA1BB1cos60=L23vΔt

    同理
    L 2 = L 1 − 3 2 v Δ t = L − 2 3 2 v Δ t , L 3 = L 2 − 3 2 v Δ t = L − 3 3 2 v Δ t , ⋯ ⋯ L n = L − n 3 2 v Δ t L_2=L_1-\frac{3}{2} v \Delta t=L-2 \frac{3}{2} v \Delta t,\\ \\ \\ L_3=L_2-\frac{3}{2} v \Delta t=L-3 \frac{3}{2} v \Delta t, \\ \\ \cdots \cdots L_n=L-n \frac{3}{2} v \Delta t L2=L123vΔt=L223vΔt,L3=L223vΔt=L323vΔt,⋯⋯Ln=Ln23vΔt

    L n → 0 L_n \rightarrow 0 Ln0 时三艘飞船相聚, 得 t = n Δ t = 2 L 3 v t=n \Delta t=\frac{2 L}{3 v} t=nΔt=3v2L。 每艘飞船走过的路程 s = v t = 2 L 3 s=v t=\frac{2 L}{3} s=vt=32L.

    解法2

    因三艘飞船都作等速率曲线运动, 而任一时刻三艘飞船的位置都在正三角形的三个顶点上, 即速度沿三角形中心的分速度不变, 指向三角形中心的分速度
    v ′ = v cos ⁡ 3 0 ∘ v^{\prime}=v \cos 30^{\circ} v=vcos30
    沿三角形中心的位移
    s ′ = L 2 cos ⁡ 30 ° s'=\frac{L}{2\cos 30°} s=2cos30°L
    则时间 t = s ′ v ′ = 2 L 3 v t=\frac{s'}{v'}=\frac{2L}{3v} t=vs=3v2L
    从开始到相遇每艘飞船走过的路程为
    s = v t = 2 L 3 s=vt=\frac{2L}{3} s=vt=32L

    3. 问题 2-2

    如果三艘飞船的速度各不相等,那么很显然,最终相遇点不会是原等边三角形的中心。显然相遇点会偏向速度更慢的飞船。

    例如, v A > v B > v C v_A>v_B>v_C vA>vB>vC,大致的运行轨迹如下所示:
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    mysql当前数据库获取所有表名及字段名的sql
    云表:只需3步,让你搞懂低代码和传统开发有什么区别
    (附源码)springboot人体健康检测微信小程序 毕业设计 012142
    Ceph 在Linux上的使用
    加载.md文件
    金仓数据库 KingbaseGIS 使用手册(6.2. 管理函数)
    目标资产主动信息收集
    【C++11】final与override
    网络安全与国家安全
    vue-echart的使用
  • 原文地址:https://blog.csdn.net/weixin_42301220/article/details/127000390