Swiftgram/Display/Spring.swift
2016-04-18 01:30:55 +03:00

67 lines
1.4 KiB
Swift

import Foundation
struct ViewportItemSpring {
let stiffness: CGFloat
let damping: CGFloat
let mass: CGFloat
var velocity: CGFloat = 0.0
init(stiffness: CGFloat, damping: CGFloat, mass: CGFloat) {
self.stiffness = stiffness
self.damping = damping
self.mass = mass
}
}
private func a(a1: CGFloat, _ a2: CGFloat) -> CGFloat
{
return 1.0 - 3.0 * a2 + 3.0 * a1
}
private func b(a1: CGFloat, _ a2: CGFloat) -> CGFloat
{
return 3.0 * a2 - 6.0 * a1
}
private func c(a1: CGFloat) -> CGFloat
{
return 3.0 * a1
}
private func calcBezier(t: CGFloat, _ a1: CGFloat, _ a2: CGFloat) -> CGFloat
{
return ((a(a1, a2)*t + b(a1, a2))*t + c(a1)) * t
}
private func calcSlope(t: CGFloat, _ a1: CGFloat, _ a2: CGFloat) -> CGFloat
{
return 3.0 * a(a1, a2) * t * t + 2.0 * b(a1, a2) * t + c(a1)
}
private func getTForX(x: CGFloat, _ x1: CGFloat, _ x2: CGFloat) -> CGFloat {
var t = x
var i = 0
while i < 4 {
let currentSlope = calcSlope(t, x1, x2)
if currentSlope == 0.0 {
return t
} else {
let currentX = calcBezier(t, x1, x2) - x
t -= currentX / currentSlope
}
i += 1
}
return t
}
func bezierPoint(x1: CGFloat, _ y1: CGFloat, _ x2: CGFloat, _ y2: CGFloat, _ x: CGFloat) -> CGFloat
{
var value = calcBezier(getTForX(x, x1, x2), y1, y2)
if value >= 0.997 {
value = 1.0
}
return value
}