← 返回
用交互动画理解折射角 (Snell 定律可视化)
2025-09-17
当一束光从一种介质(折射率 n₁)进入另一种介质(折射率 n₂)时,传播方向会发生改变,这就是折射。其定量关系由经典的 Snell 定律 给出:
n₁ · sin θ₁ = n₂ · sin θ₂
其中:
- n₁, n₂ 分别是第一、第二介质的折射率
- θ₁ 是入射角(光线与法线之间的夹角)
- θ₂ 是折射角(折射光线与法线之间的夹角)
下面这个交互式组件可以帮助你更直观地理解:拖动滑块修改第二介质折射率 n₂,或在上方拖动光线,观察折射角变化及全反射出现的瞬间。
First Medium
n1 = 1
Second Medium
n2 = 1.50
Normal
0.013
n21.5
交互玩法
- 拖动下方滑块:连续调整折射率 n₂ (范围 0.01 → 3)
- 在上方光线区域左右拖动:改变入射角 θ₁
- 当 n₁ > n₂ 且入射角足够大时,会出现 全反射(看不到折射光,仅看到反射延长线)
- 点击右下角 Replay 按钮:重新播放预设演示动画
视觉元素说明
元素 | 含义 |
---|---|
水平线 | 两种介质分界面 |
竖虚线 | 法线(Normal) |
左上角彩色入射光 | Incident Ray |
下方彩色折射光 | Refracted Ray(若全反射则消失) |
虚线延长 | 入射光/折射光的投影或延长线 |
弧形与 θ₁ / θ₂ 标注 | 对应的入射/折射角 |
Snell 定律与临界角
当从高折射率介质进入低折射率介质 (n₁ > n₂) 时,折射角 θ₂ 会比入射角 θ₁ 更大。随着 θ₁ 增大,θ₂ 逐渐逼近 90°。当 θ₂ → 90° 时,对应的入射角称为 临界角 θc:
若 θ₁ > θc,折射不再发生,光线完全被反射回第一介质——这就是全反射。
动画实现要点
本组件基于 motion
:
- 使用
useMotionValue
管理 n₂、入射角、路径插值进度等状态 - 使用
useTransform
将角度/比例映射为 SVG 坐标、文本位置、颜色渐变 - 基于
AnimationSequence
实现一段自动演示序列 - 通过手势 (
onPan
) 将用户拖动位置映射为角度 - 通过
marker
和自定义<path>
绘制箭头
核心计算:
function calculateRefractionAngle(n1: number, n2: number, theta1: number) {
const s = (n1 / n2) * Math.sin(theta1);
if (s > 1 || s < -1) return null; // 全反射
return Math.asin(s);
}
可以做的扩展
- 支持多段介质(例如:空气 → 玻璃 → 水)
- 展示反射光与菲涅尔系数(反射率/透射率)
- 增加色散:不同波长(颜色)对应不同折射率
- 展示波前(用一组平行线代替光线)
- 添加“临界角”动态提示与公式推导动画
- 添加播放速度与暂停控制
总结
交互式物理可视化能让抽象公式建立直觉联系。借助 Motion 的声明式动画与 SVG 的矢量表达,我们能快速构建一个既美观又具教育意义的光学演示组件。
如果你对更多物理/数学可视化感兴趣,欢迎继续关注后续内容 👋
行内公式示例:,以及临界角 与折射率关系 。
块级公式测试: