平滑滚动/惯性滚动/动量滚动

9

我在Android中有一个由矩阵控制平移的OpenGL ES视图。我正在尝试找到一种方法来获得类似于Google地图应用程序或iPhone中看到的动量滚动的提示。谢谢。

2个回答

11

如果你的问题是2D的,那就很简单:

  1. 需要在每个帧中获取经过的时间。
  2. 你的onTouch函数将会找到手指的加速度。我忘了从距离中如何获取加速度的公式。应该是具有时间变量的位置的二阶导数。但你应该始终将deltaX、deltaY转换为加速度。为了简单起见,你不需要放置精确的值。编辑:我不知道为什么我没有看到,但函数都在那里...

    acceleration.x = 2(newposition.x - position.x - speed.x * elapsedTime) / (elapsedTime * elapsedTime);

  3. 一旦你有了加速度,你就可以用这段代码设置新位置。这就是2D物理动力学的简单应用。通过加速度,你可以找到你的速度,并且通过速度,你可以找到你的下一个位置。

    speed.x = (float) (mass * acceleration.x * elapsed + speed.x);
    speed.y = (float) (mass * acceleration.y * elapsed + speed.y);
    
    
    position.x += mass * acceleration.x / 2 * elapsed * elapsed + speed.x * elapsed;
    position.y += mass * acceleration.y / 2 * elapsed * elapsed + speed.y * elapsed;
    
    
    speed.x *= friction;
    speed.y *= friction;
    
    质量和摩擦力将帮助您定义它的移动速度和自然减速的速度。如果您必须向后滚动以减速,则可能需要微调代码,因为这种动态并不完美。
    在每个帧结束时,您需要将加速度重置为(0,0)。在每个新的触摸事件后的每个新帧中,应将加速度设置为某些值。它应该运行得非常好 :)

1
看了你的回答,我想知道当你的速度公式需要加速度时,你是如何获得加速度的速度...一个依赖于另一个? - Dan
不直接计算速度,而是使用加速度可能会得到更好的结果。初始速度和加速度为0。因此,您必须在某个地方保存速度以将其添加到以下帧中。加速度就是每帧之间的变化量。加速度可以是deltaX,deltaY。实际速度将是deltaX * elapsedTime + lastSpeed。这样,即使一帧需要很长时间或很短的时间,速度也会被正确计算。其他参数模拟了一些物理效应,如惯性和摩擦力。您真的不希望它无限滚动。 - Loïc Faure-Lacroix

1
  1. 测量视图滚动的速度。
  2. 检测用户停止滚动的时间。
  3. 逐渐减少滚动视图的滚动速度。

类似这样:

public void redraw() {
    myScrollView.ySpeed = myScrollView.lastY-myScrollView.y;
    myScrollView.xSpeed = myScrollView.lastX-myScrollView.x;
    if (!userIsScrolling && ySpeed > 0) {
        ySpeed--;
    }
    if (!userIsScrolling && xSpeed > 0) {
        xSpeed--;
    }
    myScrollView.lastY = myScrollView.y;
    myScrollView.y += ySpeed;
    myScrollView.lastX = myScrollView.x;
    myScrollView.x += xSpeed;
}

public void userStoppedScrolling() {
    userIsScrolling = false;
}

谢谢,你知道我怎样才能控制用户滚动的速度吗?现在它只是计算用户手指起始位置和结束位置之间的差值,然后将其放入矩阵中。 - jfisk
抱歉,我对Android不够熟悉,无法提供有关触摸位置等具体信息的帮助。 - Jumhyn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接