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

从simd_float4x4矩阵提取平移、旋转、缩放组件(含缩放时旋转提取问题)

从simd_float4x4变换矩阵中提取平移、旋转、缩放组件(不使用RealityKit的Transform)

我需要在不依赖RealityKit的Transform等引擎专属工具的前提下,从simd_float4x4变换矩阵中提取平移、旋转、缩放三个组件。目前已经找到提取平移和缩放的方法,但旋转提取存在问题:当变换矩阵包含缩放时,使用simd_quatf(matrix)无法得到正确结果。

let transform = Transform(
    scale: simd_float3(1, 2, 3),
    rotation: simd_quatf(angle: 0.5, axis: .init(0, 1, 0)),
    translation: simd_float3(10, 20, 30)
)
let matrix = transform.matrix


// Translation: OK
let translation = simd_float3(
    matrix.columns.3.x,
    matrix.columns.3.y,
    matrix.columns.3.z
)
print("Expected: \( transform.translation )")
print("Actual:   \( translation )")
// Expected: SIMD3<Float>(10.0, 20.0, 30.0)
// Actual:   SIMD3<Float>(10.0, 20.0, 30.0)


// Scale: OK
let scale = simd_float3(
    simd_length(simd_float3(matrix.columns.0.x, matrix.columns.0.y, matrix.columns.0.z)),
    simd_length(simd_float3(matrix.columns.1.x, matrix.columns.1.y, matrix.columns.1.z)),
    simd_length(simd_float3(matrix.columns.2.x, matrix.columns.2.y, matrix.columns.2.z))
)
print("Expected: \( transform.scale )")
print("Actual:   \( scale )")
// Expected: SIMD3<Float>(1.0, 2.0, 3.0)
// Actual:   SIMD3<Float>(1.0, 2.0, 3.0)


// Rotation: doesn't match
let rotation = simd_quatf(matrix)
print("Expected: \( transform.rotation )")
print("Actual:   \( rotation )")
// Expected: simd_quatf(real: 0.9689124, imag: SIMD3<Float>(0.0, 0.24740396, 0.0))
// Actual:   simd_quatf(real: 1.2757674, imag: SIMD3<Float>(0.0, 0.37579384, 0.0))

更新

我确认正确的旋转值是可以提取的,因为RealityKit的Transform类能做到这一点,但不清楚其内部计算逻辑。示例中,从组件初始化的Transform1和从矩阵初始化的Transform2都能提取到相同的正确旋转值,但直接用simd_quatf(matrix)得到的结果却不匹配:

// Initialize from components
let transform1 = Transform(
    scale: simd_float3(10, 20, 30),
    rotation: simd_quatf(angle: 0.5, axis: .init(0, 1, 0)),
    translation: simd_float3(1, 2, 3)
)

// Initialize from composed matrix
let matrix = simd_float4x4([
    [8.7758255, 0.0, -4.7942553, 0.0],
    [0.0, 20.0, 0.0, 0.0],
    [14.382767, 0.0, 26.327477, 0.0],
    [1.0, 2.0, 3.0, 1.0]
])
let transform2 = Transform(matrix: matrix)

// Both extract the same value:
// simd_quatf(real: 0.9689124, imag: SIMD3<Float>(0.0, 0.24740396, 0.0))
print( transform1.rotation )
print( transform2.rotation )

// This doesn't extract the same value:
// simd_quatf(real: 3.745107, imag: SIMD3<Float>(0.0, 1.2801384, 0.0))
print( simd_quatf(matrix) )

// They don't match visually either
anchor1.orientation = transform1.rotation
anchor2.orientation = transform2.rotation    // same as anchor 1
anchor3.orientation = simd_quatf(matrix)     // different from anchor 1 & 2

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:25:50