展平simd_float4x4矩阵的优雅方法

时间:2019-05-22 11:45:51

标签: arrays swift simd

我想将simd_float4x4simd_float3x3矩阵展平为单个float数组。

对于常规数组,我会使用

let arr = [[1,2,3],[4,5,6],[7,8,9]]
print(arr.flatMap { $0 })

如何优雅地为simd_float4x4simd_float3x3结构执行此操作?

我目前正在使用

extension simd_float3x3 {
    var array: [Float] {
        return [columns.0.x, columns.0.y, columns.0.z,
                columns.1.x, columns.1.y, columns.1.z,
                columns.2.x, columns.2.y, columns.2.z]
    }
}

let arr = simd_float3x3.init()
print(arr.array.compactMap({$0}))

2 个答案:

答案 0 :(得分:1)

好吧,看来向量float3float4已经实现了map(通过实现Sequence / Collection协议)。

所以我们唯一要做的就是为矩阵实现Collection

extension simd_float3x3: Collection {
    public var startIndex: Int {
        return 0
    }

    public var endIndex: Int {
        return 3 // for `sims_float4x4` it would be 4, number of columns
    }

    public func index(after i: Int) -> Int {
        return i + 1
    }
}

现在我们可以这样做:

let matrix: simd_float3x3 = initCodeForTheMatrix()
matrix.flatMap { $0 }

您可以声明此方便的子协议,以避免为所有矩阵类型键入相同的startIndexindex(after:)

public protocol SIMDCollection: Collection {}
extension SIMDCollection {
    public var startIndex: Int {
        return 0
    }

    public func index(after i: Int) -> Int {
        return i + 1
    }
}

// And use it like this:
extension simd_float3x3: SIMDCollection {
    public var endIndex: Int {
        return 3
    }
}

extension simd_float4x4: SIMDCollection {
    public var endIndex: Int {
        return 4
    }
}

extension simd_float3x2: SIMDCollection {
    public var endIndex: Int {
        return 3
    }
}

// etc

它甚至可以走得更远,因为endIndex对于具有相同simd_floatX_Y和任何X的所有Y都是相同的。甚至是*float**double*还是什么都没关系。

答案 1 :(得分:0)

优雅的眼神在情人眼中。到目前为止,我已经提出了这个建议:

let s = simd_float3x3(simd_float3(1, 2, 3), simd_float3(4, 5, 6), simd_float3(7, 8, 9)) 

let y = (0..<3).flatMap { x in (0..<3).map { y in s[x][y] } }

print(y)
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]