主题
Quaternion
概览
| 字段 | 值 |
|---|---|
| Kind | Data · 数据 Data |
| Realm | common |
四元数用 x、y、z、w 四个分量描述三维旋转,同时提供 Euler、Pitch、Yaw、Roll 等角度属性,便于在分量表示与欧拉角表示之间切换。它既能从轴角、欧拉角或直接给定分量构造旋转,也支持单位化、求逆、求共轭、点积比较与插值过渡,并可取出前、上、右方向向量或转换为 Matrix3x3。需要校验旋转数据是否可用时,可通过 IsFinite、IsUnit、IsValid 判断。
适用场景
在为物体指定朝向、或在两个朝向之间做平滑过渡时最常用,典型做法是先由方向算出偏航角,再用 Quaternion.FromEulerAngles 构造旋转参数交给对应接口使用。读取朝向、变换向量或与其他旋转做比较时,也会先取得一个四元数实例再访问其属性与函数。
使用要点
通过 Quaternion.New(x, y, z, w) 或等价简写 Quaternion(x, y, z, w) 构造实例,也可用 Quaternion.Identity()、Quaternion.FromAxisAngle(axis, angle)、Quaternion.FromEulerAngles(x, y, z) 直接得到旋转。拿到实例后,常用 quat:GetForward()、quat:GetUp()、quat:GetRight() 取方向向量,用 quat:Apply(v) 把向量按该旋转变换,用 quat:GetUnit()、quat:GetInverse()、quat:GetConjugate() 得到单位化或逆旋转结果,用 quat:Dot(other) 做比较,用 quat:GetMatrix() 取等价的 Matrix3x3 表示。需要在两个旋转之间插值时使用 Slerp 或 Nlerp,并可用 quat:GetPitch()、quat:GetYaw()、quat:GetRoll() 或 quat.Euler 读回角度。
注意事项
实例只能通过 Quaternion.New(...) 或简写 Quaternion(...) 构造,禁止使用冒号语法;Identity、FromAxisAngle、FromEulerAngles、Slerp、Nlerp 都是直接产出新四元数的入口。分量属性 x、y、z、w 与欧拉角属性 Euler、Pitch、Yaw、Roll 描述的是同一个旋转,混用两套表示时要注意它们相互对应。参与旋转计算前可用 IsUnit 判断或 GetUnit 取单位化结果,并用 IsFinite、IsValid 检查数据是否合法。
代码示例
构造单位四元数并读取分量与欧拉角
lua
-- @runtime client
-- 四元数常用于表示旋转,这里先构造一个单位四元数 (x, y, z, w)
local quat = Quaternion.New(0, 0, 0, 1)
-- 直接读取公开属性:分量、欧拉角与姿态角
print("分量:", quat.x, quat.y, quat.z, quat.w)
print("欧拉角:", quat.Euler, "Pitch/Yaw/Roll:", quat.Pitch, quat.Yaw, quat.Roll)
-- 用实例方法检查数值特性,避免手写比较逻辑
print("模长:", quat:Length(), "模长平方:", quat:LengthSquare())
print("是否单位四元数:", quat:IsUnit(), "是否有效:", quat:IsValid())
-- GetUnit 返回归一化后的新四元数,原实例本身不会被修改
local unitQuat = quat:GetUnit()
print("归一化副本模长:", unitQuat:Length(), "是否有限:", unitQuat:IsFinite())从轴角与欧拉角构造并插值旋转
lua
-- @runtime client
-- 由轴角构造:绕 Y 轴旋转 90 度(静态工厂用点语法调用)
local axisQuat = Quaternion.FromAxisAngle(Vector3.New(0, 1, 0), math.rad(90))
-- 由欧拉角构造:绕 Y 轴旋转 45 度
local eulerQuat = Quaternion.FromEulerAngles(0, math.rad(45), 0)
local blended = Quaternion.Slerp(axisQuat, eulerQuat, 0.5)
print("插值分量:", blended.x, blended.y, blended.z, blended.w)
-- 用四元数旋转一个方向向量,并读取旋转后的朝向信息
local rotated = blended:Apply(Vector3.New(0, 0, 1))
print("旋转后的向量:", rotated.x, rotated.y, rotated.z)
local forward = blended:GetForward()
print("前方向:", forward.x, forward.y, forward.z)
print("点积:", blended:Dot(eulerQuat), "俯仰角(弧度):", blended:GetPitch())属性 (8)
| Name | 类型 | 默认值 | 说明 |
|---|---|---|---|
x | Float | - | 四元数的 X 分量(向量部分)。 |
y | Float | - | 四元数的 Y 分量(向量部分)。 |
z | Float | - | 四元数的 Z 分量(向量部分)。 |
w | Float | - | 四元数的 W 分量(标量部分)。 |
Euler | Vector3 | - | 四元数对应的欧拉角(弧度,ZXY 顺序),只读。 |
Pitch | Float | - | 绕 X 轴的俯仰角,单位为弧度。 |
Yaw | Float | - | 绕 Y 轴的偏航角,单位为弧度。 |
Roll | Float | - | 绕 Z 轴的翻滚角,单位为弧度。 |
关联类型
函数 (28)
New
签名:New(x: Float, y: Float, z: Float, w: Float) -> Quaternion
创建一个新的四元数实例。
| 参数 | 类型 | 说明 |
|---|---|---|
x | Float | - |
y | Float | - |
z | Float | - |
w | Float | - |
返回值 Quaternion
示例代码
构造单位四元数
lua
-- @runtime client
local q = Quaternion.New(0, 0, 0, 1)
print(string.format('单位四元数: x=%.1f y=%.1f z=%.1f w=%.1f', q.x, q.y, q.z, q.w))Identity
签名:Identity() -> Quaternion
返回一个单位四元数,其分量为 (0, 0, 0, 1),表示无旋转。
返回值 Quaternion
示例代码
获取单位四元数(无旋转)
lua
-- @runtime client
local q = Quaternion.Identity()
print(string.format('单位四元数: x=%.1f y=%.1f z=%.1f w=%.1f', q.x, q.y, q.z, q.w))
print('是否单位四元数:', q:IsUnit())FromAxisAngle
签名:FromAxisAngle(axis: Vector3, angle: Float) -> Quaternion
静态构造函数,根据传入的旋转轴与旋转角度生成一个新的 Quaternion 实例,用于表示绕该轴旋转指定角度的旋转。
| 参数 | 类型 | 说明 |
|---|---|---|
axis | Vector3 | 旋转轴(应为单位向量) |
angle | Float | 旋转角度(弧度) |
返回值 Quaternion
示例代码
从轴角构造四元数
lua
-- @runtime client
-- 绕 Y 轴旋转 90 度(弧度)
local axis = Vector3.New(0, 1, 0)
local angle = 1.5708 -- 90 度
local q = Quaternion.FromAxisAngle(axis, angle)
print(string.format('四元数: x=%.4f y=%.4f z=%.4f w=%.4f', q.x, q.y, q.z, q.w))FromEulerAngles
签名:FromEulerAngles(x: Float, y: Float, z: Float) -> Quaternion
根据欧拉角(弧度,ZXY 顺序)构造四元数,参数依次为 pitch、yaw、roll。
| 参数 | 类型 | 说明 |
|---|---|---|
x | Float | Pitch(弧度) |
y | Float | Yaw(弧度) |
z | Float | Roll(弧度) |
返回值 Quaternion
示例代码
从欧拉角构造四元数
lua
-- @runtime client
-- FromEulerAngles 的参数按 Meta 标注传入弧度:pitch, yaw, roll
local q = Quaternion.FromEulerAngles(math.rad(30), math.rad(45), 0)
print(string.format('Pitch=%.4f Yaw=%.4f Roll=%.4f', q.Pitch, q.Yaw, q.Roll))Slerp
签名:Slerp(a: Quaternion, b: Quaternion, t: Float) -> Quaternion
在两个四元数之间进行球面线性插值,返回插值后的四元数。
| 参数 | 类型 | 说明 |
|---|---|---|
a | Quaternion | - |
b | Quaternion | - |
t | Float | 插值因子 [0, 1] |
返回值 Quaternion
示例代码
球面线性插值两个四元数(恒定角速度)
lua
-- @runtime client
local q1 = Quaternion.Identity()
local q2 = Quaternion.FromAxisAngle(Vector3.New(0,1,0), 1.5708)
local mid = Quaternion.Slerp(q1, q2, 0.5) -- 50% 球面插值
print(string.format('Slerp 结果 w=%.4f', mid.w))Nlerp
签名:Nlerp(a: Quaternion, b: Quaternion, t: Float) -> Quaternion
对两个四元数 a 和 b 进行归一化线性插值,返回插值结果。
| 参数 | 类型 | 说明 |
|---|---|---|
a | Quaternion | - |
b | Quaternion | - |
t | Float | 插值因子 [0, 1] |
返回值 Quaternion
示例代码
归一化线性插值两个四元数
lua
-- @runtime client
local q1 = Quaternion.Identity()
local q2 = Quaternion.FromAxisAngle(Vector3.New(0,1,0), 1.5708)
local mid = Quaternion.Nlerp(q1, q2, 0.5) -- 50% 插值
print(string.format('插值结果 w=%.4f', mid.w))Length
签名:Length() -> Float
计算四元数的模长(即各分量平方和的平方根)。
返回值 Float
示例代码
计算四元数的长度
lua
-- @runtime client
-- 构造一个非单位四元数
local q = Quaternion(1, 2, 3, 4)
-- 计算长度
local len = q:Length()
print("四元数长度:", len)LengthSquare
签名:LengthSquare() -> Float
计算四元数长度的平方,即各分量平方和。
返回值 Float
示例代码
计算四元数长度的平方
lua
-- @runtime client
-- 构造一个四元数
local q = Quaternion(1, 2, 3, 4)
-- 计算长度的平方
local lenSq = q:LengthSquare()
print("四元数长度平方:", lenSq)Normalize
签名:Normalize() -> void
将当前四元数归一化为单位四元数,使其模长为1。归一化后的四元数保持相同的旋转方向,但长度变为1。
返回值 void
示例代码
归一化四元数并验证长度
lua
-- @runtime client
-- 创建一个非单位四元数
local q = Quaternion(1, 2, 3, 4)
-- 归一化
q:Normalize()
-- 输出归一化后的分量
print("x:", q.x, "y:", q.y, "z:", q.z, "w:", q.w)
-- 验证长度是否接近 1
print("Length:", q:Length())Inverse
签名:Inverse() -> void
将当前四元数就地修改为其逆四元数。逆四元数表示与原旋转相反的旋转。
返回值 void
示例代码
求四元数的逆(反向旋转)
lua
-- @runtime client
local q = Quaternion.FromAxisAngle(Vector3.New(0,1,0), 1.5708)
q:Inverse()
-- Inverse 会就地修改当前四元数
print('逆四元数 w:', q.w)GetUnit
签名:GetUnit() -> Quaternion
返回当前四元数的单位化版本,即方向相同但长度为1的四元数。
返回值 Quaternion
示例代码
获取四元数的单位化版本
lua
-- @runtime client
-- 构造一个非单位四元数
local q = Quaternion(1, 2, 3, 4)
-- 获取单位四元数
local unitQ = q:GetUnit()
print("单位化后的长度:", unitQ:Length())GetConjugate
签名:GetConjugate() -> Quaternion
返回当前四元数的共轭四元数。共轭四元数的虚部取反,实部不变。
返回值 Quaternion
示例代码
获取四元数的共轭
lua
-- @runtime client
-- 构造一个四元数
local q = Quaternion(1, 2, 3, 4)
-- 获取共轭
local conj = q:GetConjugate()
print("共轭四元数:", conj.x, conj.y, conj.z, conj.w)GetInverse
签名:GetInverse() -> Quaternion
返回当前四元数的逆。逆四元数表示相反的旋转,满足 q * q:GetInverse() = 单位四元数。
返回值 Quaternion
示例代码
获取四元数的逆
lua
-- @runtime client
local q = Quaternion.FromEulerAngles(0, math.rad(90), 0)
local qInv = q:GetInverse()
print('逆四元数 w:', qInv.w)GetMatrix
签名:GetMatrix() -> Matrix3x3
返回当前四元数对应的 3x3 旋转矩阵。
返回值 Matrix3x3
示例代码
获取四元数对应的旋转矩阵
lua
-- @runtime client
local q = Quaternion.FromEulerAngles(0, math.rad(90), 0)
local matrix = q:GetMatrix()
print('旋转矩阵:', tostring(matrix))GetVectorV
签名:GetVectorV() -> Vector3
返回四元数中由 x、y、z 三个分量组成的向量部分,返回值类型为 Vector3。
返回值 Vector3
示例代码
取出四元数的向量部分并与分量比对
lua
-- @runtime client
-- 构造一个绕 Y 轴旋转 90 度的四元数
local rot = Quaternion.FromEulerAngles(0, math.pi / 2, 0)
-- 取出四元数的向量部分 (x, y, z)
local v = rot:GetVectorV()
print(v.x, v.y, v.z)
-- 与四元数自身的 x/y/z 分量逐项比对,确认向量部分一致
print(v.x == rot.x, v.y == rot.y, v.z == rot.z)
-- 输出向量部分的模长,便于观察数值规模
print(v.Magnitude)SetToIdentity
签名:SetToIdentity() -> void
将当前四元数重置为单位四元数(即无旋转状态)。
返回值 void
示例代码
将四元数设置为单位四元数
lua
-- @runtime client
-- 创建一个非单位四元数
local q = Quaternion(1, 2, 3, 4)
-- 设置为单位四元数
q:SetToIdentity()
-- 输出分量,应为 (0, 0, 0, 1)
print("x:", q.x, "y:", q.y, "z:", q.z, "w:", q.w)
-- 验证是否为单位四元数
print("IsUnit:", q:IsUnit())Dot
签名:Dot(rhs: Quaternion) -> Float
计算两个四元数的分量点积,返回标量。比较旋转差异前应先归一化;单位四元数 q 与 -q 表示同一旋转,因此应结合点积绝对值判断旋转接近程度,不能简单把带符号点积越大解释为旋转越接近。
⚙ 只有单位四元数的点积才在 [-1, 1] 范围内。q 与 -q 的点积为 -1,但它们表示同一旋转;不可把 -1 解释为旋转方向完全相反。
| 参数 | 类型 | 说明 |
|---|---|---|
rhs | Quaternion | - |
返回值 Float
示例代码
计算两个四元数的点积
lua
-- @runtime client
-- 创建两个四元数
local q1 = Quaternion(1, 0, 0, 0)
local q2 = Quaternion(0, 1, 0, 0)
-- 计算点积
local dot = q1:Dot(q2)
print("点积:", dot)GetRotationAngleAxis
签名:GetRotationAngleAxis() -> Vector4
返回该四元数对应的旋转轴与旋转角度,结果封装为 Vector4,分量排布为 (axisX, axisY, axisZ, angle)。
返回值 Vector4
示例代码
获取轴角表示
lua
-- @runtime client
local q = Quaternion.FromEulerAngles(0, math.rad(90), 0)
local axisAngle = q:GetRotationAngleAxis()
print('旋转轴:', axisAngle.x, axisAngle.y, axisAngle.z)
print('旋转角度(弧度):', axisAngle.w)GetPitch
签名:GetPitch() -> Float
返回当前四元数旋转的俯仰角(Pitch),单位为弧度。
返回值 Float
示例代码
读取俯仰角
lua
-- @runtime client
local q = Quaternion.FromEulerAngles(math.rad(30), 0, 0)
local pitch = q:GetPitch()
print('俯仰角(弧度):', pitch)GetYaw
签名:GetYaw() -> Float
获取四元数对应的偏航角(弧度)。
返回值 Float
示例代码
读取偏航角
lua
-- @runtime client
local q = Quaternion.FromEulerAngles(0, math.rad(60), 0)
local yaw = q:GetYaw()
print('偏航角(弧度):', yaw)GetRoll
签名:GetRoll() -> Float
返回当前四元数对应的翻滚角(Roll),单位为弧度。
返回值 Float
示例代码
读取翻滚角
lua
-- @runtime client
local q = Quaternion.FromEulerAngles(0, 0, math.rad(45))
local roll = q:GetRoll()
print('翻滚角(弧度):', roll)IsFinite
签名:IsFinite() -> Bool
检查四元数的所有分量(x, y, z, w)是否均为有限数值,即不是 NaN 或无穷大。
返回值 Bool
示例代码
检查四元数分量是否均为有限数
lua
-- @runtime client
-- 构造一个正常四元数
local q = Quaternion(1, 2, 3, 4)
-- 检查是否有限
print("IsFinite:", q:IsFinite())IsUnit
签名:IsUnit() -> Bool
判断当前四元数是否为单位四元数,即模长是否接近 1。
返回值 Bool
示例代码
检查四元数是否为单位四元数
lua
-- @runtime client
-- 构造一个单位四元数
local q = Quaternion.Identity()
-- 检查是否为单位四元数
print("IsUnit:", q:IsUnit())IsValid
签名:IsValid() -> Bool
判断当前四元数是否有效,即所有分量均为有限数值且模长为1(单位四元数)。
返回值 Bool
示例代码
检查四元数是否有效(有限且单位)
lua
-- @runtime client
-- 构造一个单位四元数
local q = Quaternion.Identity()
-- 检查是否有效
print("IsValid:", q:IsValid())Apply
签名:Apply(v: Vector3) -> Vector3
把该四元数所表示的旋转作用到传入的 Vector3 上,并返回旋转后的新向量。
| 参数 | 类型 | 说明 |
|---|---|---|
v | Vector3 | - |
返回值 Vector3
示例代码
将旋转应用到向量
lua
-- @runtime client
local q = Quaternion.FromEulerAngles(0, math.rad(90), 0)
local forward = Vector3.New(0, 0, 1)
local rotated = q:Apply(forward)
print('旋转后的向量:', tostring(rotated))GetForward
签名:GetForward() -> Vector3
返回该四元数所对应坐标系的前向向量,返回值类型为 Vector3。
返回值 Vector3
示例代码
获取前向向量
lua
-- @runtime client
local q = Quaternion.FromEulerAngles(0, math.rad(90), 0)
local forward = q:GetForward()
print('前向向量:', tostring(forward))GetUp
签名:GetUp() -> Vector3
返回该四元数所对应坐标系的上向向量,返回值类型为 Vector3。
返回值 Vector3
示例代码
获取上向向量
lua
-- @runtime client
local q = Quaternion.FromEulerAngles(math.rad(-90), 0, 0)
local up = q:GetUp()
print('上向向量:', tostring(up))GetRight
签名:GetRight() -> Vector3
返回该四元数所对应坐标系的右向向量,返回值类型为 Vector3。
返回值 Vector3
示例代码
获取右向向量
lua
-- @runtime client
local q = Quaternion.FromEulerAngles(0, math.rad(90), 0)
local right = q:GetRight()
print('右向向量:', tostring(right))