Skip to content

Instantly share code, notes, and snippets.

@Koshimizu-Takehito
Created July 25, 2020 07:27
Show Gist options
  • Save Koshimizu-Takehito/57673d57bf75cd056e8f979cc269d2f0 to your computer and use it in GitHub Desktop.
Save Koshimizu-Takehito/57673d57bf75cd056e8f979cc269d2f0 to your computer and use it in GitHub Desktop.
import SwiftUI
import enum Accelerate.vDSP
public struct AnimatableVector<V: BinaryFloatingPoint>: VectorArithmetic, Hashable {
public var values: [Double]
public init<V: BinaryFloatingPoint>(values: [V]) {
self.values = values.map(Double.init)
}
public init<V: BinaryFloatingPoint>(_ values: V...) {
self.init(values: values)
}
public init() {
self.init(values: [Double]())
}
public func values(_: Void = ()) -> [V] {
return values.map(V.init)
}
}
// MARK: - VectorArithmetic
public extension AnimatableVector {
mutating func scale(by rhs: Double) {
values = vDSP.multiply(rhs, values)
}
var magnitudeSquared: Double {
vDSP.sum(vDSP.multiply(values, values))
}
}
// MARK: - AdditiveArithmetic
public extension AnimatableVector {
static var zero: Self {
Self()
}
static func + (lhs: Self, rhs: Self) -> Self {
let count = max(lhs.values.count, rhs.values.count)
let lhs: [Double] = Array(unsafeUninitializedCapacity: count, initializingWith: zeroPadding(count: count, values: lhs.values))
let rhs: [Double] = Array(unsafeUninitializedCapacity: count, initializingWith: zeroPadding(count: count, values: rhs.values))
return Self(values: vDSP.add(lhs, rhs))
}
static func - (lhs: Self, rhs: Self) -> Self {
let count = max(lhs.values.count, rhs.values.count)
let lhs: [Double] = Array(unsafeUninitializedCapacity: count, initializingWith: zeroPadding(count: count, values: lhs.values))
let rhs: [Double] = Array(unsafeUninitializedCapacity: count, initializingWith: zeroPadding(count: count, values: rhs.values))
return Self(values: vDSP.subtract(lhs, rhs))
}
private static func zeroPadding(count: Int, values: [Double]) -> (_ buffer: inout UnsafeMutableBufferPointer<Double>, _ n: inout Int) -> Void {
return { buffer, n in
for i in 0..<count {
buffer[i] = (i < values.count) ? values[i] : 0
}
n = count
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment