当前位置: 首页 > news >正文

【数组】求两个匀速运动质点的相交或最小距离

题目描述

两个质点初始位置,朝向角和速度分别为:(x0,y0,yaw0,v0),(x1,y1,yaw1,v1),它们在t=0时刻匀速直行运动,问它们是否会在同一时刻相交,如果不会,找出它们距离最小的时刻。相交判断距离小于1e-6,算法要求高效。

代码实现

import matheps = 1e-6def check(x0, y0, yaw0, v0, x1, y1, yaw1, v1):# 计算两个质点的速度分量v0_x = v0 * math.cos(yaw0)v0_y = v0 * math.sin(yaw0)v1_x = v1 * math.cos(yaw1)v1_y = v1 * math.sin(yaw1)# 相对速度分量(质点0相对于质点1)dv_x = v0_x - v1_xdv_y = v0_y - v1_y# 初始相对位置dx = x0 - x1dy = y0 - y1# 如果相对速度为0if dv_x == 0 and dv_y == 0:# 距离会始终不变,计算距离distance = math.sqrt(dx ** 2 + dy ** 2)return (True, 0.0) if distance < eps else (False, 0.0)# 如果相对速度不为0else:# 计算最小距离对应的时刻t_mint_min = -(dx * dv_x + dy * dv_y) / (dv_x ** 2 + dv_y ** 2)# 时刻不能为负数t_min = max(t_min, 0.0)# 计算t_min时刻的距离x0_t = x0 + v0_x * t_miny0_t = y0 + v0_y * t_minx1_t = x1 + v1_x * t_miny1_t = y1 + v1_y * t_mindistance = math.sqrt((x0_t - x1_t)**2 + (y0_t - y1_t)**2)# 判断是否相交(小于eps)is_intersect = distance < epsreturn (is_intersect, t_min)

t_min = -(dx * dv_x + dy * dv_y) / (dv_x ** 2 + dv_y ** 2)

要理解这个公式,我们需要从距离的数学表达和极值求解的角度来分析。

  1. 距离的平方公式

设时刻 t 时,两个质点的位置分别为:

  • 质点0: (x0(t),y0(t))=(x0+v0x⋅t, y0+v0y⋅t)(x_0(t), y_0(t)) = (x_0 + v_{0x} \cdot t,\ y_0 + v_{0y} \cdot t)(x0(t),y0(t))=(x0+v0xt, y0+v0yt)

  • 质点1: (x1(t),y1(t))=(x1+v1x⋅t, y1+v1y⋅t)(x_1(t), y_1(t)) = (x_1 + v_{1x} \cdot t,\ y_1 + v_{1y} \cdot t)(x1(t),y1(t))=(x1+v1xt, y1+v1yt)

两质点的距离平方为:

d2(t)=[x0(t)−x1(t)]2+[y0(t)−y1(t)]2d^2(t) = \left[ x_0(t) - x_1(t) \right]^2 + \left[ y_0(t) - y_1(t) \right]^2d2(t)=[x0(t)x1(t)]2+[y0(t)y1(t)]2

将位置表达式代入,展开后得到:

d2(t)=[(x0−x1)+(v0x−v1x)⋅t]2+[(y0−y1)+(v0y−v1y)⋅t]2d^2(t) = \left[ (x_0 - x_1) + (v_{0x} - v_{1x}) \cdot t \right]^2 + \left[ (y_0 - y_1) + (v_{0y} - v_{1y}) \cdot t \right]^2d2(t)=[(x0x1)+(v0xv1x)t]2+[(y0y1)+(v0yv1y)t]2

  1. 定义简化变量

为了简化推导,定义:

  • 初始位置差: dx=x0−x1dx = x_0 - x_1dx=x0x1dy=y0−y1dy = y_0 - y_1dy=y0y1

  • 相对速度分量: dvx=v0x−v1x,dvy=v0y−v1ydv_x = v_{0x} - v_{1x} , dv_y = v_{0y} - v_{1y}dvx=v0xv1xdvy=v0yv1y

此时,距离平方可简化为:

d2(t)=(dx+dvx⋅t)2+(dy+dvy⋅t)2d^2(t) = \left( dx + dv_x \cdot t \right)^2 + \left( dy + dv_y \cdot t \right)^2d2(t)=(dx+dvxt)2+(dy+dvyt)2

  1. 求距离的最小值(极值)

距离 d(t) 是非负连续函数,且 d(t) 与 d2(t)d^2(t)d2(t) 的单调性一致(因为平方是单调递增函数)。因此,最小化 d(t) 等价于最小化 d2(t)d^2(t)d2(t)

d2(t)d^2(t)d2(t) 关于 t 求导,并令导数为0(极值点的必要条件):

步骤1:展开 d2(t)d^2(t)d2(t)

d2(t)=(dx)2+2⋅dx⋅dvx⋅t+(dvx)2⋅t2+(dy)2+2⋅dy⋅dvy⋅t+(dvy)2⋅t2d^2(t) = (dx)^2 + 2 \cdot dx \cdot dv_x \cdot t + (dv_x)^2 \cdot t^2 + (dy)^2 + 2 \cdot dy \cdot dv_y \cdot t + (dv_y)^2 \cdot t^2d2(t)=(dx)2+2dxdvxt+(dvx)2t2+(dy)2+2dydvyt+(dvy)2t2

步骤2:求导

对 t 求导:

ddt[d2(t)]=2⋅dx⋅dvx+2⋅(dvx)2⋅t+2⋅dy⋅dvy+2⋅(dvy)2⋅t\frac{d}{dt} \left[ d^2(t) \right] = 2 \cdot dx \cdot dv_x + 2 \cdot (dv_x)^2 \cdot t + 2 \cdot dy \cdot dv_y + 2 \cdot (dv_y)^2 \cdot tdtd[d2(t)]=2dxdvx+2(dvx)2t+2dydvy+2(dvy)2t

步骤3:令导数为0,解 t

ddt[d2(t)]=0\frac{d}{dt} \left[ d^2(t) \right] = 0dtd[d2(t)]=0 ,消去公因子 2 后:

dx⋅dvx+(dvx)2⋅t+dy⋅dvy+(dvy)2⋅t=0dx \cdot dv_x + (dv_x)^2 \cdot t + dy \cdot dv_y + (dv_y)^2 \cdot t = 0dxdvx+(dvx)2t+dydvy+(dvy)2t=0

整理关于 t 的项:

t⋅[(dvx)2+(dvy)2]+(dx⋅dvx+dy⋅dvy)=0t \cdot \left[ (dv_x)^2 + (dv_y)^2 \right] + \left( dx \cdot dv_x + dy \cdot dv_y \right) = 0t[(dvx)2+(dvy)2]+(dxdvx+dydvy)=0

解得:

t=−dx⋅dvx+dy⋅dvy(dvx)2+(dvy)2t = -\frac{dx \cdot dv_x + dy \cdot dv_y}{(dv_x)^2 + (dv_y)^2}t=(dvx)2+(dvy)2dxdvx+dydvy

这就是最小距离对应的时刻 tmint_{\text{min}}tmin

  1. 物理意义
  • 公式中的分子 dx⋅dvx+dy⋅dvydx \cdot dv_x + dy \cdot dv_ydxdvx+dydvy 是初始位置差与相对速度的“点积”,反映了“位置差”与“相对速度”的对齐程度。

  • 分母 (dvx)2+(dvy)2(dv_x)^2 + (dv_y)^2(dvx)2+(dvy)2 是相对速度的大小平方,保证分母非负。

tmin≥0t_{\text{min}} \geq 0tmin0 时,该时刻对应两质点距离最小的时刻;若 tmin<0t_{\text{min}} < 0tmin<0 ,则最小距离出现在 t=0 (因为质点从 t=0 开始运动,更早的时刻无意义)。

总结

公式 tmin=−dx⋅dvx+dy⋅dvy(dvx)2+(dvy)2t_{\text{min}} = -\frac{dx \cdot dv_x + dy \cdot dv_y}{(dv_x)^2 + (dv_y)^2}tmin=(dvx)2+(dvy)2dxdvx+dydvy 是通过求导找极值推导得到的,它给出了两质点距离最小时的时刻(仅考虑 t≥0t \geq 0t0 的情况)。

http://www.dtcms.com/a/389174.html

相关文章:

  • 新手向:Python爬虫原理详解,从零开始的网络数据采集指南
  • OKZOO进军HealthFi:承接AIoT,引领Health-to-Earn
  • Halcon 相机标定
  • 腾讯混元发布集成翻译模型Hunyuan-MT-Chimera-7B,已开放体验
  • mybatis-plus扩展
  • 从x.ai到VSCode:一个AI编程助手的意外之旅
  • SQLite vs MySQL:核心SQL语法差异全面解析
  • 【每日算法】两数相加 LeetCode
  • ActiveMQ底层原理与性能优化
  • Ceph IO流程分段上传(1)——InitMultipart
  • 大数据毕业设计选题推荐-基于大数据的农作物产量数据分析与可视化系统-Hadoop-Spark-数据可视化-BigData
  • 【回归之作】学校实训作业:Day04面向对象思想编程
  • Ubuntu20.04或者Ubuntu24.04 TypeC-连接屏幕不显示问题
  • 【SQLSERVER】SQL Server 表导出与导入
  • postgresql和mongodb谁的地位更高
  • RK3588+复旦微JFM7K325T工业控制解决方案
  • RabbitMQ全方位解析
  • 云望无人机图传原理,无人机图传方式哪种好
  • 无人机50公里遥控模块技术要点与难点
  • 【三维重建】Octree-GS:基于LOD的3DGS实时渲染(TPAMI2025)
  • 《深度拆解3D开放世界游戏中角色攀爬系统与地形碰撞网格动态适配的穿透卡顿复合故障》
  • 数据库mysql连接池:从原理到实践的全面解析
  • # 深入理解栈、栈帧与递归:从迭代与递归归并排序双视角解析
  • Django 完整项目开发:博客系统
  • FPGA部署视觉模型
  • 课后实验实验拓扑:
  • 二阶段 docker 构建
  • React原理二
  • 116.block design 设计中设置的DDR起始地址的作用是什么
  • 报名中|2025 Maple 用户大会