Skip to content

Quaternion ​

概览 ​

字段值
KindData · 数据 Data
Realmcommon

四元数用 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类型默认值说明
xFloat-四元数的 X 分量(向量部分)。
yFloat-四元数的 Y 分量(向量部分)。
zFloat-四元数的 Z 分量(向量部分)。
wFloat-四元数的 W 分量(标量部分)。
EulerVector3-四元数对应的欧拉角(弧度,ZXY 顺序),只读。
PitchFloat-绕 X 轴的俯仰角,单位为弧度。
YawFloat-绕 Y 轴的偏航角,单位为弧度。
RollFloat-绕 Z 轴的翻滚角,单位为弧度。

关联类型 ​

函数 (28) ​

New ​

签名:New(x: Float, y: Float, z: Float, w: Float) -> Quaternion

创建一个新的四元数实例。

参数类型说明
xFloat-
yFloat-
zFloat-
wFloat-

返回值 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 实例,用于表示绕该轴旋转指定角度的旋转。

参数类型说明
axisVector3旋转轴(应为单位向量)
angleFloat旋转角度(弧度)

返回值 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。

参数类型说明
xFloatPitch(弧度)
yFloatYaw(弧度)
zFloatRoll(弧度)

返回值 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

在两个四元数之间进行球面线性插值,返回插值后的四元数。

参数类型说明
aQuaternion-
bQuaternion-
tFloat插值因子 [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 进行归一化线性插值,返回插值结果。

参数类型说明
aQuaternion-
bQuaternion-
tFloat插值因子 [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 解释为旋转方向完全相反。

参数类型说明
rhsQuaternion-

返回值 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 上,并返回旋转后的新向量。

参数类型说明
vVector3-

返回值 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))