Skip to content

Instantly share code, notes, and snippets.

@rsmoz
Last active August 29, 2015 14:20
Show Gist options
  • Save rsmoz/999722c71d6c8bc5e7f4 to your computer and use it in GitHub Desktop.
Save rsmoz/999722c71d6c8bc5e7f4 to your computer and use it in GitHub Desktop.
typealias DimensionVector = [Double]
protocol Dimensional {
var dimensions: DimensionVector { get } //Could make an Interpolable protocol to use instead of Double, but that would be a confusing design pattern in the case of Ints
static func itemFromDimensions(fromDimensions: DimensionVector) -> Self?
}
func inBetween(a: Double, b: Double, byRatio ratio: Double) -> Double {
let diff = abs(a - b)
let calcd = ratio * diff
let adjusted = (a<b) ? a + calcd : a - calcd
return adjusted
}
func interpolated<T: Dimensional>(a: T, b: T, byRatio ratio: Double) -> T? {
let aDimensions = a.dimensions
let bDimensions = b.dimensions
if aDimensions.count != bDimensions.count {
//Will never happen if type T implements Dimensional properly.
assertionFailure("The type \(T.self)'s implementation of Dimensional's `dimensions` property is flawed")
return nil
}
let zpd = Array(Zip2(aDimensions, bDimensions))
let rescaled = zpd.map { inBetween($0.0, $0.1, byRatio: ratio) }
let result = T.itemFromDimensions(rescaled)
return result
}
extension CGPoint: Dimensional {
var dimensions: DimensionVector {
return [x,y].map { Double($0) }
}
static func itemFromDimensions(fromDimensions: DimensionVector) -> CGPoint? {
return CGPoint(x: fromDimensions[0], y: fromDimensions[1])
}
}
extension CGSize: Dimensional {
var dimensions: DimensionVector {
return [width, height].map { Double($0) }
}
static func itemFromDimensions(fromDimensions: DimensionVector) -> CGSize? {
return CGSize(width: fromDimensions[0], height: fromDimensions[1])
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment