从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
相关产品推荐
相关产品推荐

