【问题标题】:Changing the speed of a circular motion改变圆周运动的速度
【发布时间】:2010-10-31 02:31:17
【问题描述】:

我正在寻找一种方法来平滑地增加或减少圆周运动的速度。

使用圆的参数方程,我可以随时间移动一个圆:

x = center_x + radius * sin(time * speed)
y = center_y + radius * cos(time * speed)

这种方法的问题是我不能简单地使用speed = speed + 1 来加速对象,因为它会导致运动不平稳。这是有道理的,因为每帧都会根据绝对值而不是相对于对象的先前位置重新计算 x 和 y 值。

另一种方法可能是使用表示对象速度的向量,然后对向量应用圆周运动:

v_x = radius * sin(time * speed)
v_y = radius * cos(time * speed)
x = x + v_x
y = y + v_y

这种方法的问题是,如果我改变速度,那么半径就会增大或缩小。这是有道理的,因为运动是相对于当前位置的,所以如果我改变速度,时间基本上会被跳过。

我能想到的一个可行的实现是使用一个从对象指向圆心的向量。然后我可以通过使用垂直向量计算圆在对象位置的切线,对其进行归一化并按速度缩放。我还没有实现这个,因为这样的问题似乎有点矫枉过正,所以如果存在更简单的解决方案,请告诉我。谢谢!

【问题讨论】:

    标签: performance simulation physics geometry


    【解决方案1】:

    速度是角度的变化率,速度的变化只影响最后一个区间的角度变化,所以:

    delta = time - lastTime
    angle = angle + delta * speed
    
    x = center_x + radius * sin(angle)
    y = center_y + radius * cos(angle)
    

    lastTime 必须保存最后一个循环的时间,明白吗?

    【讨论】:

    • 这和我的第二个实现有同样的问题。自己试试吧。
    • 啊,我的实现错了,不是这个算法(看起来很愚蠢)。谢谢!
    【解决方案2】:

    你自己说过:你想改变角速度。现在,在现实世界中,角速度的变化受到物体的角惯性的限制。这意味着它不能以 1 步“离散”。

    相反,角速度是角加速度的积分。角位置是角速度的积分。

    所以对于恒定的角加速度,你可以说

    速度(t) = t*acc + vel[t=0].

    角度( t ) = t 2 * acc/2 + vel[t=0] * t + 角度[t=0].

    然后你可以用角度的sin和cos来计算你的carthesian位置。

    角加速度可以(相当)离散地变化。

    【讨论】:

    • 这很好地解释了我做错了什么,感谢您帮助我理解这一点!
    【解决方案3】:

    如果你只是在做speed = speed + 1,你就没有正确使用加速。更一般地说,你想这样做:

    accel = 1;
    speed = speed + (accel * timeDelta);
    

    此外,accel = 1 以弧度表示的角速度变化非常大 - 请尝试使用较小的值,例如 PI / 16。如果您需要如此大的加速度并希望最大限度地减少抖动运动的可见性,您可能需要尝试使用一些运动模糊。

    【讨论】:

      【解决方案4】:

      为了平滑增加角速度,您需要添加角加速度

      x = 半径 * cos(theta)
      y = 半径 * sin(theta)

      theta(t) = theta(0) + omega(0)*t + 0.5 * alpha * t^2

      其中 t 是时间,theta(0) 是时间 0 的角位置,omega(0) 是时间 0 的角速度(将等于您的速度参数),而 alpha 是角加速度参数,您选择合适的。

      【讨论】:

      • 这假设 alpha 保持不变。当然,您可以以分段连续的方式执行此操作 - 将其运行到时间 T,然后在该状态下重新初始化。
      【解决方案5】:

      使用

      time * speed
      

      表示圆圈已经走了多远是错误的。只有当速度永远不变时才有意义。

      相反,您需要将行驶的距离存储在一个变量中,然后根据当前速度和自上次绘制以来的时间间隔将变量增加一个量。

      其他人必须使用加速的建议也很好。尝试类似

      v = v + a;
      d = d + delta * v;
      
      x = center_x + radius * sin(d)
      y = center_y + radius * cos(d)
      

      【讨论】:

      • time * speed 有时确实有意义,当您的时间步长并不总是相等时(例如,如果您跳帧)。
      • 你的想法是对的。您可能希望有一个可变的时间步长,如 d += v * delta; v += a * 增量;当然,这是欧拉积分。 Runge-Kutta 会更准确。
      【解决方案6】:

      您需要从角速度的角度来考虑这一点。 您正在计算角度θ,作为时间*速度,如果速度是传统的速度感,即距离/时间,这没有意义。角速度是角度/时间(即弧度/秒或度/秒)。常规速度将是应用角速度后起点和终点之间的距离/时间。

      【讨论】:

        【解决方案7】:
        x = center_x + radius * sin(time * speed + offset)
        y = center_y + radius * cos(time * speed + offset)
        
        def change_speed(new_speed):
            offset = time * (speed - new_speed) + offset
            speed = new_speed
        

        offset 可以从 0 或任何值开始...它用于保持连续性,因为

        time * old_speed + old_offset == time * new_speed + new_offset
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-05
          • 1970-01-01
          • 1970-01-01
          • 2012-11-13
          • 2013-02-11
          相关资源
          最近更新 更多