Qt Quick 粒子系统(七):扩散方向模型
一、粒子往哪里飞
上一篇解决了"粒子从哪里出生"的问题,这一篇解决"粒子往哪里飞"。粒子的运动方向由 Emitter 的 velocity(速度)和 acceleration(加速度)属性控制,两者的值类型都是 Direction(实际为 StochasticDirection)。
Qt Quick 粒子系统提供了三种基础 Direction 模型和一种组合模型:AngleDirection(极坐标模型)、PointDirection(直角坐标模型)、TargetDirection(目标点模型)、CumulativeDirection(组合模型)。每种模型对应不同的参数输入方式,选错模型会导致参数难以理解或效果不符合预期。
本文围绕"你有什么参数就用什么模型"展开,先讲数学本质,再通过五个示例演示参数调优。
二、开发环境与版本说明
本文所有代码基于以下环境验证(验证日期:2026-06-10):
- Qt 版本:6.8.2
- 编译器:MinGW 64-bit
- 操作系统:Windows 11
- 构建工具:CMake 3.29
Direction 的 API 从 Qt 5 起稳定,Qt 6.5+ 均可直接运行本文代码。
三、原理分析:三种方向模型
3.1 Direction 的角色
Direction 是 Emitter 的 velocity 和 acceleration 属性的值类型(实际类型为 StochasticDirection,Direction 是其基类)。它定义了一个速度向量或加速度向量:
velocity:粒子诞生时的初始速度,决定粒子往哪飞、飞多快acceleration:粒子受到的持续加速度,决定粒子的运动轨迹如何变化
一个粒子的运动可以用物理公式描述:
位置 = 初始位置 + velocity × t + 0.5 × acceleration × t²
两者可以使用不同的 Direction 模型。
3.2 AngleDirection:极坐标模型
输入参数:角度(angle)+ 速度大小(magnitude)
数学本质:将速度分解为直角坐标分量
vx = magnitude × cos(angle)
vy = magnitude × sin(angle)
关键属性:
| 属性 | 含义 | 默认值 |
|---|---|---|
angle |
发射角度(度) | 0 |
angleVariation |
角度随机偏移范围 | 0 |
magnitude |
速度大小(像素/秒) | 0 |
magnitudeVariation |
速度大小随机偏移范围 | 0 |
角度参考系:Qt Quick 的角度以向右为 0 度,顺时针递增:
适用场景:均匀扩散、锥形喷射、定向发射。当你知道"往哪个角度飞、飞多快"时,用 AngleDirection。
3.3 PointDirection:直角坐标模型
输入参数:x 方向速度 + y 方向速度
数学本质:直接指定速度的 x/y 分量,不做坐标转换
vx = x + random(-xVariation, +xVariation)
vy = y + random(-yVariation, +yVariation)
关键属性:
| 属性 | 含义 | 默认值 |
|---|---|---|
x |
x 方向速度分量 | 0 |
xVariation |
x 方向随机偏移 | 0 |
y |
y 方向速度分量 | 0 |
yVariation |
y 方向随机偏移 | 0 |
适用场景:抛物线轨迹(配合 acceleration)、定向流动、锥形扩散。当你知道"x 方向飞多快、y 方向飞多快"时,用 PointDirection。
3.4 TargetDirection:目标点模型
输入参数:目标点坐标(targetX, targetY)+ 速度大小(magnitude)
数学本质:速度方向指向目标点,大小由 magnitude 决定
dx = targetX - particle.x
dy = targetY - particle.y
angle = atan2(dy, dx)
vx = magnitude × cos(angle)
vy = magnitude × sin(angle)
关键属性:
| 属性 | 含义 | 默认值 |
|---|---|---|
targetX |
目标点 x 坐标(相对于 Emitter) | 0 |
targetY |
目标点 y 坐标(相对于 Emitter) | 0 |
targetItem |
目标 Item(优先级高于 targetX/targetY) | 无 |
targetVariation |
目标点随机偏移范围 | 0 |
magnitude |
速度大小(像素/秒) | 0 |
magnitudeVariation |
速度大小随机偏移 | 0 |
proportionalMagnitude |
是否按距离比例计算速度 | false |
targetItem:可以直接绑定一个 QML Item 作为目标,优先级高于 targetX/targetY。无需手动计算坐标偏移。
proportionalMagnitude:设为 true 时,magnitude 被解释为"距目标点距离的倍数/秒"——粒子离目标远时速度快,接近时自动减速,产生自然的减速效果。默认 false,magnitude 为固定像素/秒。
适用场景:粒子汇聚、吸引效果、指向性发射。当你知道"飞向哪个点"时,用 TargetDirection。
3.5 CumulativeDirection:组合模型
数学本质:多个 Direction 的速度向量叠加
v_total = v_1 + v_2 + ... + v_n
CumulativeDirection 内部可以包含任意数量的子 Direction,它们的速度向量会相加。比如一个 AngleDirection(随机扩散)叠加一个 PointDirection(定向偏移),粒子就同时具有扩散和定向运动。
适用场景:需要同时具有多种运动特征的复合效果。
3.6 选型决策
3.7 velocity 与 acceleration 的配合
两者的常见搭配模式:
- 纯 velocity:粒子匀速直线运动
- velocity + acceleration:粒子变速运动(如抛物线)
- 纯 acceleration(velocity 为 0):粒子从静止开始加速
最经典的配合是"抛物线":velocity 用 AngleDirection(斜向上),acceleration 用 PointDirection(向下重力)。
四、代码实现
4.1 Direction_AngleSpread.qml:水平扩散
每个示例都由 ParticleSystem、ImageParticle、Emitter 三部分组成,后续只展示 Emitter 核心配置。
Emitter {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
width: 1; height: 1
emitRate: 100
lifeSpan: 4000
size: 10
velocity: AngleDirection {
angle: 0 // 基础方向向右
angleVariation: 30 // ±30° 随机偏移
magnitude: 150 // 速度 150 像素/秒
magnitudeVariation: 50 // 速度在 [100, 200] 之间随机
}
}
结果是粒子从左侧向右呈扇形扩散,扩散角度 60 度(±30 度)。magnitudeVariation 是双向偏移(150 ± 50),速度不同的粒子形成参差不齐的前沿。
4.2 Direction_Parabolic.qml:抛物线轨迹
Emitter {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
width: 1; height: 1
emitRate: 60
lifeSpan: 4000
size: 10
velocity: AngleDirection {
angle: 315
angleVariation: 10
magnitude: 200
magnitudeVariation: 30
}
acceleration: PointDirection {
y: 80
}
}
velocity:angle: 315 表示向右上方发射。推导过程:0° 是正右方,90° 是正下方(顺时针递增),270° 是正上方,所以 315° = 270° + 45° = 向上偏右 45°。magnitude: 200 表示初始速度较快。
acceleration:PointDirection { y: 80 } 表示持续向下的加速度,模拟重力。注意 y: 80 是正值——在 Qt Quick 坐标系中,y 轴向下为正,所以正值 y 表示向下的加速度。
两者配合产生了抛物线轨迹:粒子先斜向上飞,速度逐渐被重力抵消,到达最高点后开始下落。
4.3 Direction_ConeSpread.qml:锥形扩散
Emitter {
x: parent.width / 2
y: 80
width: 1; height: 1
emitRate: 100
lifeSpan: 3000
size: 10
velocity: PointDirection {
x: 0
y: 150
xVariation: 60
yVariation: 30
}
}
x: 0, y: 150 表示基础方向向下,xVariation: 60 表示水平方向 ±60 的随机偏移,yVariation: 30 表示垂直方向 ±30 的随机偏移。结果是粒子从顶部向下呈锥形扩散——中心区域粒子密集,边缘稀疏。
这个效果用 AngleDirection 也能实现(angle: 90, angleVariation: 20),但 PointDirection 更直观地表达了"向下为主、左右偏移"的意图。
4.4 Direction_TargetSpread.qml:目标扩散
Emitter {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
width: 1; height: 1
emitRate: 80
lifeSpan: 4000
size: 10
velocity: TargetDirection {
targetX: targetPoint.x - emitter.x
targetY: targetPoint.y - emitter.y
targetVariation: 80
magnitude: 120
magnitudeVariation: 30
}
}
targetX / targetY:目标点坐标是相对于 Emitter 的偏移量。代码中用 targetPoint.x - emitter.x 和 targetPoint.y - emitter.y 通过 QML 属性绑定动态计算——当目标点或 Emitter 移动时,偏移量会自动更新,粒子始终指向目标点。
实际上 TargetDirection 还提供了 targetItem 属性,可以直接绑定目标 Item,不需要手动计算偏移:targetItem: targetPoint。本例使用手动计算是为了演示相对坐标的含义。
targetVariation: 80:目标点的随机偏移范围。设为 80 意味着粒子不会精确飞向目标点,而是在目标点周围 80 像素的范围内随机偏移,避免"激光"效果。目标点用一个带呼吸动画的绿色圆形标记。
4.5 Direction_Cumulative.qml:组合方向
Emitter {
anchors.centerIn: parent
width: 1; height: 1
emitRate: 100
lifeSpan: 4000
size: 10
velocity: CumulativeDirection {
AngleDirection {
angle: 0
angleVariation: 360
magnitude: 80
}
PointDirection {
x: 50
y: 0
}
}
}
CumulativeDirection 包含两个子 Direction,速度向量逐帧相加:
- AngleDirection:
angleVariation: 360全方向随机扩散,提供均匀的"圆" - PointDirection:
x: 50向右偏移,提供一个向右的"箭头"
叠加后,向右的粒子更快,向左的粒子更慢甚至反向——整体呈现"被风吹动的烟花"效果。
4.6 同一个效果,不同实现——模型对比
以"锥形扩散"(粒子从顶部向下发射,水平随机偏移)为例,两种模型都能实现:
// 方案 A:AngleDirection —— 用角度控制扩散范围
velocity: AngleDirection {
angle: 90; angleVariation: 20; magnitude: 150
}
// 方案 B:PointDirection —— 用 X/Y 分量控制偏移范围
velocity: PointDirection {
x: 0; y: 150; xVariation: 60; yVariation: 30
}
两者的视觉效果接近,但参数直觉不同:AngleDirection 的 angleVariation 控制扇形张角,适合喷射、火焰;PointDirection 的 xVariation 控制左右散布范围,适合雨帘、瀑布。选型依据:角度是核心参数用 AngleDirection,水平/垂直偏移量是核心参数用 PointDirection。
4.7 参数调优指南
| 模型 | 想要效果 | 调整什么 |
|---|---|---|
| AngleDirection | 扩散更集中/更宽 | 减小/增大 angleVariation(0~360) |
| AngleDirection | 粒子飞得更远 | 增大 magnitude |
| PointDirection | 左右散布更宽 | 增大 xVariation |
| PointDirection | 上下散布更宽 | 增大 yVariation |
| 抛物线 | 更陡峭 | 增大 acceleration.y |
| 抛物线 | 飞得更高 | 增大 velocity.magnitude |
规律:Variation 控制随机范围,基础值控制主运动方向和强度。
五、运行效果
Direction_AngleSpread.qml:红色星形粒子从页面左侧向右呈扇形扩散,扩散角度约 60 度。
Direction_Parabolic.qml:青色星形粒子从左侧斜向上发射,在重力作用下画出优美的抛物线轨迹。
Direction_ConeSpread.qml:黄色星形粒子从顶部向下呈锥形扩散,中心密集、边缘稀疏。
Direction_TargetSpread.qml:绿色星形粒子从左侧向右上方的目标点汇聚,但不精确——带有自然的发散效果。目标点有呼吸动画标记。
Direction_Cumulative.qml:青色星形粒子从中心向四面八方扩散,但整体有明显的向右漂移趋势。
六、适用边界与限制条件
- velocity 只能设一个 Direction,不能同时写两个。需要多种方向叠加时用 CumulativeDirection,但
velocity和acceleration可以使用不同的模型 - acceleration 最常用 PointDirection(如重力
y: 80),AngleDirection 和 TargetDirection 作为加速度时语义不直观 - 角度单位是度(0-360),向右为 0 度,顺时针递增:0° = 右,90° = 下,270° = 上
- TargetDirection 的 targetX/targetY 是相对坐标(相对于 Emitter)。不想手动计算可以用
targetItem直接绑定目标 Item - magnitude 为 0 时粒子静止,有 acceleration 则从静止开始加速
- angleVariation 为 0 时所有粒子精确沿 angle 方向发射;为 360 时完全随机扩散
七、总结
回到开头的问题:“粒子往哪里飞?”——答案取决于你手里的参数。
三种模型的核心区别在于参数输入方式:AngleDirection 用极坐标,PointDirection 用直角坐标,TargetDirection 用目标点坐标。同一个效果(如锥形扩散)可以用不同模型实现,选择取决于哪个模型的参数更符合你的直觉。需要多种运动叠加时,CumulativeDirection 将多个向量相加。
velocity 和 acceleration 可以混用不同模型。最经典的配合是"抛物线":velocity 用 AngleDirection 控制发射方向,acceleration 用 PointDirection 模拟重力。
下一篇讲解粒子的随机性参数——位置、速度、角度。
资源下载:qml_particlesystem —— 包含完整的、可运行的代码
系列目录
- 上一篇:Qt Quick 粒子系统(六):五种发射区域的精确控制
- 本文:Qt Quick 粒子系统(七):扩散方向模型
- 下一篇:Qt Quick 粒子系统(八):发射随机性——位置、速度与角度
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)