スクロール速度などを計測して処理をする、というときとかに使う感じのやつ。
(ちなみに previous
系は全部 0
で初期化しておきます)
// 毎フレームここが呼ばれる想定
- (void)updateVelocity:(NSInteger)position
// 初期位置が設定されていなかったら設定だけする
if (self.previousPosition == 0) {
self.previousTime = [[NSDate date] timeIntervalSince1970];
self.previousPosition = position;
return;
}
// 離散時間
const NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
const NSTimeInterval deltaTime = now - self.previousTime;
// 位置の差分
const NSInteger deltaPosition = position - self.previousPosition;
// 前回差分からの速度を計算
CGFloat velocity = (CGFloat)deltaPosition / deltaTime;
// 速度の差分を計算
const CGFloat deltaVelocity = velocity - self.previousVelocity;
// 加速度を加算
const CGFloat acceleration = deltaVelocity / deltaTime;
// 加速度の差分を計算
const CGFloat deltaAcceleration = acceleration - self.previousAcceleration;
// 加速度を更新
self.acceleration += deltaAcceleration;
// 求めた加速度から現在の速度を計算
self.velocity += self.acceleration * deltaTime;
NSLog(@"VELOCITY : %10.2f", self.velocity);
NSLog(@"ACCELERATION: %10.2f", self.acceleration);
// 計算したものを次のフレームのために「前回データ」として保持しておく
self.previousTime = now;
self.previousPosition = position;
self.previousVelocity = velocity;
self.previousAcceleration = acceleration;
}
解説
離散で位置と速度を扱うため、まず前回との差分時間を出す。いわゆる $⊿t$ 。
そしてその時間を単位として計算をしていく。
位置から速度を算出
まずは前回位置からの差分で速度を算出する。
差分位置 ÷ 離散時間で求まる。
速度から加速度を計算
位置と同じように速度も同様にして「前回の速度から今回の速度」の差分を取り、それを離散時間で割り、加速度を求める。
加速度の差分を計算
さらに、加速度も同様にして前回からの変化量を計算する。
つまり結論として、 位置、速度、加速度すべてで該当フレーム時間での微分 を行っているイメージ。
(加速度の微分はなんていうのか知らないけど)
加速度から速度を計算
最後に求めた加速度の変化量を現在の加速度に足し込む。
その計算結果が現時点での実際の加速度となる。
そして今まで利用してきた離散時間当たりの速度を求める。
計算としては今まさに計算が終わった現時点の加速度に離散時間をかけることで、その瞬間の実際の速度の変化が計算できる。
そしてそれを現在の速度に足すことにより、最終的に「今の速度」を求めることができる。
あとはこの速度を元にやりたい処理を行えばいい。(例えば慣性だったり、速度に応じた演出だったり)