2D网格两点间玩家渐进圆周运动的数学方程求解
2D网格中点到点的渐进圆周运动方案
核心运动方程推导
要实现从点P(Px, Py)到点Q(Qx, Qy)的渐进圆周运动,需先确定圆弧路径的关键参数,再构建参数化运动方程:
基础参数计算
- 两点间距:
d = √[(Qx-Px)² + (Qy-Py)²] - PQ中点M:
Mx=(Px+Qx)/2,My=(Py+Qy)/2 - PQ的垂直方向单位向量(决定圆弧凸向,可选上下侧):
上侧:vec_perp = (-(Qy-Py)/d, (Qx-Px)/d)
下侧:vec_perp = ((Qy-Py)/d, -(Qx-Px)/d)
- 两点间距:
确定圆弧圆心与半径
设圆弧半径为R(需满足R ≥ d/2,否则无法形成包含PQ的圆弧),圆心O到PQ的垂直距离h = √(R² - (d/2)²),则圆心坐标:Ox = Mx + vec_perp.x * hOy = My + vec_perp.y * h角度参数与运动方程
- 初始角(O到P的角度):
θP = atan2(Py-Oy, Px-Ox) - 目标角(O到Q的角度):
θQ = atan2(Qy-Oy, Qx-Ox) - 调整角度差方向(确保沿最短圆弧或指定方向运动,若θQ < θP则
θQ += 2π) - 最终参数化运动方程(t∈[0,1],t=0在P点,t=1到达Q点):
θ(t) = θP + t*(θQ - θP) x(t) = Ox + R*cosθ(t) y(t) = Oy + R*sinθ(t)
若要实现渐进平滑的速度变化(比如从静止开始加速,接近终点减速),可替换线性t为缓动函数,例如正弦缓动:
ease_t = sin(π*t/2) θ(t) = θP + ease_t*(θQ - θP)- 初始角(O到P的角度):
与角度差、距离的关联
该运动完全依赖角度差与两点距离:
- 两点距离d:决定圆弧的弦长,直接限制了圆弧半径的最小值(
R≥d/2),同时通过d=2Rsin(θ/2)关联圆心角θ(θ为θQ与θP的差值)。 - 角度差θ:即圆弧对应的圆心角,决定了运动的弧度范围,角度变化的方向(顺时针/逆时针)决定了路径的走向,角度变化的速率(结合缓动函数)决定了运动的平滑程度。
示例伪代码
import math # 定义起始点P与目标点Q Px, Py = 0, 0 Qx, Qy = 4, 0 # 计算基础参数 d = math.hypot(Qx - Px, Qy - Py) Mx, My = (Px + Qx)/2, (Py + Qy)/2 # 设置圆弧半径(需大于d/2) R = 3 h = math.sqrt(R**2 - (d/2)**2) # 选择上侧圆弧的垂直向量 perp_x = -(Qy - Py)/d perp_y = (Qx - Px)/d Ox, Oy = Mx + perp_x * h, My + perp_y * h # 计算初始与目标角度 theta_P = math.atan2(Py - Oy, Px - Ox) theta_Q = math.atan2(Qy - Oy, Qx - Ox) # 调整角度差为逆时针方向 if theta_Q < theta_P: theta_Q += 2 * math.pi # 获取t时刻的位置(t∈[0,1]) def get_circular_position(t): # 可选:启用正弦缓动 # ease_t = math.sin(t * math.pi / 2) # theta = theta_P + ease_t * (theta_Q - theta_P) theta = theta_P + t * (theta_Q - theta_P) x = Ox + R * math.cos(theta) y = Oy + R * math.sin(theta) return (x, y)
内容的提问来源于stack exchange,提问作者tester0101
相关产品推荐
相关产品推荐

