C语言 计算滚动惯性/动量



如何计算滚动动量滚动事件?

我明白在滚动的开始和结束处必须有两个时间戳。还必须有一个"轴变化"变量,它基本上是滚动量,没有惯性。

这是我目前负责滚动结束的代码:

if ((type == kMXTEnd || type == kMXTMovedOut) && _isScrolling)
    {
        long int finishTime = MXTimestamp();
        printf("SCEnd: Ending scroll at %ldn",finishTime-_beginTime);
        /* scrollX is the change in X axis */
        /* finishTime is time from touch down to touch up */
        printf("  * Time: %ld ChangeX: %fn",finishTime,scrollX);
        _isScrolling = FALSE;
        _originalScrollPoint = _scrollPoint;
    }

是否有可能计算出"惯性加法"?就像通过惯性获得的额外偏移量,我可以在主要滚动值之外滚动。还是需要额外的变量?

我需要这个,因为我正在编写自己的UI工具包,它并不是真正基于任何东西。

我所做的取得好成绩的方法如下:

在每个鼠标拖动事件(或触摸事件)上,存储速度(即移动量除以上一帧以来的时间)和时间戳。您只需要最后一个,所以只有两个变量。

当鼠标/触摸被释放时,检查最后一个时间戳是否足够近(我使用0.3秒)。如果是,设置一个变量intialvelocity为最后计算的速度;否则将其设置为0,以防止用户仔细选择位置时滚动。

然后在每次更新(无论是通过计时器,或每个渲染调用,取决于你是如何渲染),滚动由惯性速度*惯性tia_scroll_factor(我使用0.9)和乘以惯性速度惯性加速度(我使用0.98)

你可能想要添加一个阈值,所以滚动停止,如果惯性速度变得太小。我使用1作为阈值,因为我的渲染库使用浮点数作为坐标。如果坐标是积分,它会自己归零。

需要记住的一点是,根据方向的不同,惯性速度可以是正的,也可以是负的。

所以,在伪代码中:
OnMouseMove:
    inertialVelocity = moveDistance / (now - timeOfLastEvent)
    timeOfLastEvent = now
OnMouseUp:
    if (now - timeSinceLastEvent > 0.3f)
        inertialVelocity = 0
OnTimer/OnRender:
    // timeDelta is needed only when doing this on render events, just to make
    // it independent of the render speed. It is the time since the previous render
    scrollPosition += inertialVelocity * INERTIA_SCROLL_FACTOR * timeDelta
    inertialVelocity *= INERTIA_ACCELERATION * timeDelta
    // Keep in mind that velocity can be negative as well, hence the abs
    if (abs(inertialVelocity) < INERTIA_THRESHOLD)
        inertialVelocity = 0

您可以用"最近的轴更改"队列来模拟这一点。

如果你用相应的时间戳存储最后半秒的变化,那么你可以测试队列是否长于一个值N(即用户是否比通常更快地拖到最后)。你知道在最后半秒内走过的总距离,时间,从这些你可以得到速度。

将速度调整到合理的水平(比如…)15像素/。5秒,映射到~25px/秒),并应用负加速度(也适当缩放,对于上面的例子,说-20px/秒)每几毫秒(或尽可能快,你的系统可以轻松处理它,不要过度强调它)。

然后运行计时器,在每个刻度处更新速度(speed+=accel*time_scale),然后是位置(position+=speed*time_scale)。当速度达到0(或低于0)时终止定时器

相关内容

  • 没有找到相关文章

最新更新