You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

坐标系下粒子与线段碰撞的反射角求解问题

解决粒子与线段碰撞后的反射角计算问题

原方法失效的核心原因

  • 你用numpy.arctan2(vy-uy, vx-ux)算出的是线段从u到v的走向角度,但反射计算需要的是线段的法线方向——线段有两个相反的法线方向,选反了直接导致反射角完全错误
  • 直接用角度差Δθ = θuv - θ推导反射角,没考虑粒子是从线段哪一侧入射,再加上角度的周期性(比如超过π或低于-π),很容易出现符号或数值异常

正确计算步骤

1. 先算线段的方向向量和法向量

先得到线段u-v的方向向量:

dx = vx - ux
dy = vy - uy

再生成两个垂直于线段的单位法向量(对应线段的两侧):

# 左侧法线(垂直于线段u→v方向向左)
nx1 = -dy
ny1 = dx
# 右侧法线(垂直于线段u→v方向向右)
nx2 = dy
ny2 = -dx
# 归一化法向量(保证后续点积计算准确)
norm = numpy.sqrt(nx1**2 + ny1**2)
nx1, ny1 = nx1/norm, ny1/norm
nx2, ny2 = nx2/norm, ny2/norm

2. 生成粒子入射方向的单位向量

从入射角度θ转换为向量形式:

vx_inc = numpy.cos(θ)
vy_inc = numpy.sin(θ)

3. 选对正确的法线方向

判断粒子从线段哪一侧入射:入射方向与指向粒子所在侧的法线点积为负(因为法线指向线段外侧,入射方向是从外侧撞向线段)

dot1 = vx_inc * nx1 + vy_inc * ny1
dot2 = vx_inc * nx2 + vy_inc * ny2

# 选点积为负的法线
nx, ny = (nx1, ny1) if dot1 < 0 else (nx2, ny2)

4. 计算反射方向向量

用标准反射公式:反射向量 = 入射向量 - 2*(入射向量·法线向量)*法线向量

dot_inc_n = vx_inc * nx + vy_inc * ny
vx_ref = vx_inc - 2 * dot_inc_n * nx
vy_ref = vy_inc - 2 * dot_inc_n * ny

5. 转换为反射角

最后用arctan2得到相对于x轴的反射角:

θ_reflected = numpy.arctan2(vy_ref, vx_ref)

如果需要把角度范围从[-π, π]转成[0, 2π],可以加一步:

θ_reflected = numpy.mod(θ_reflected, 2*numpy.pi)

关键提醒

反射定律的核心是入射角等于反射角(相对于法线),不是相对于线段本身——这是原方法最容易踩的坑,一定要基于法线方向计算,而不是线段的走向角度。

内容的提问来源于stack exchange,提问作者smuecke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 23:10:31