2010-11-23 68 views
1

我想實現動態滾動的列表對象,但我有一個問題,確定基於速度應用的摩擦量(持續時間)。基於速度的動力學滾動(動量)的持續時間?

我的applyFriction()方法根據持續時間屬性均勻地降低滾動對象的速度。然而,對於每個運動使用相同的持續時間(IE:1秒)並不自然。對於具有少量速度(IE:5 - 10像素)的運動,1秒持續時間顯得很好,但對於具有大量速度(IE:100+像素)的運動在1秒持續時間內施加摩擦滾動對象似乎會減慢並停止得更快。本質上,我試圖確定每個動作的適當持續時間,以便小和大量的速度將共享一個匹配的摩擦,所以移動的對象將總是有一個恆定的「重量」。

是否有一個通用算法來確定基於不同速度的動力學運動的持續時間?


注:我在ActionScript 3.0編程和使用Tween類,以減少移動物體的通過持續時間的速度。

回答

6

更好的摩擦模型是摩擦力與速度成正比。你需要一個常數來確定力和加速度(質量,或多或少)之間的關係。寫作的關係作爲差分方程,

F[n] = -gamma * v[n-1] 
a[n] = F[n]/m 
v[n] = v[n-1] + dt * a[n] 
    = v[n-1] + dt * F[n]/m 
    = v[n-1] - dt * gamma * v[n-1]/m 
    = v[n-1] * (1 - dt*gamma/m) 

所以,如果你希望你的減速看起來流暢自然,而不是線性降低你的速度,你要挑一些常量略小於1並多次受到乘以速度這個常數。當然,這只是漸進地接近零,所以你可能想要一個閾值,低於該閾值,你可以將速度設置爲零。

因此,舉例來說:

v_epsilon = <some minimum velocity>; 
k_frict = 0.9; // play around with this a bit 

while (v > v_epsilon) { 
    v = v * k_frict; 
    usleep(1000); 
} 

v = 0; 

我想你會發現這個看起來更自然。

如果要用線性減速來近似此值,那麼您需要使花費減慢的時間與初始速度的自然對數成比例。這看起來不太正確,但它看起來會比現在更好。因爲與速度成比例的摩擦力建立了一個一階微分方程,它給出了exp(-t/tau)類型的響應,其中tau是系統的一個特性。從一個任意速度衰減到一個給定的極限與這樣的系統中的ln(v_init)成正比。)

+0

或成正比的速度平方... – 2010-11-24 00:28:20

4

我之前曾經研究過這個問題:爲什麼Android動量滾動不是感覺和iPhone一樣好?

幸運的是,a guy already got out a video camera, recorded an iPhone scrolling, and figured out what it does

當我開始工作......,我沒仔細留意滾動適用於iPhone的方式。我只是假設減速是基於Newton’s law of motion,即一個運動的物體接收一段時間後被迫停止的摩擦。過了一段時間,我意識到這實際上是而不是 iPhone(以及後來的iOS設備,如iPad)如何做到這一點。使用相機並捕捉各種iOS應用程序的幾十個滾動動作,無論列表的大小或輕彈的速度如何,在相同的時間量之後,所有滾動都會停止。您滑動的速度有多快(決定滾動的初始速度)僅確定,其中列表將停止,而不是,此時

這導致他的大大簡化的數學:

amplitude = initialVelocity * scaleFactor; 
step = 0; 

ticker = setInterval(function() { 
    var delta = amplitude/timeConstant; 
    position += delta; 
    amplitude -= delta; 
    step += 1; 
    if (step > 6 * timeConstant) { 
     clearInterval(ticker); 
    } 
}, updateInterval); 

其實,這是減速是如何在蘋果自己的PastryKit庫中實現(現在part of iAd)。它爲每個動畫節拍(16.7毫秒,目標爲60 fps)將滾動速度降低了0.95。這對應於325毫秒的時間常數。如果你是一個數學怪胎,那麼顯然你意識到滾動速度的指數性質將導致位置的指數衰減。隨着scriblling一點點,最終你會發現,

325 = -16.7/ln(0.95) 

,從而在運動:

enter image description here


你提的問題是關於時間使用。我喜歡iPhone的感覺(與Android相反)。我認爲你應該使用1,950 ms

- (1000 ms/60)/ln(0.95) * 6 = 1950 ms