在给定的时间间隔内创建平滑旋转(+ - x%)

时间:2012-09-27 17:15:53

标签: javascript math animation 3d three.js

我的场景中有一个立方体,我想以特定的起始速度给定的时间间隔旋转。
此外,立方体的终止角应该是与起始角度相同。 因此,我想到允许+ - 5%的时间间隔偏差。

以下是我目前的状态:http://jsfiddle.net/5NWab/1/
不要怀疑目前正在工作。如果我改变时间间隔,例如, '3000':http://jsfiddle.net/5NWab/2/

我的多维数据集的基本 move()方法:

Reel.prototype.move = function (delta) {
    if (this.velocity < 0 && this.mesh.rotation.x == 0) {
        return false;
    }

    // Create smooth end rotation
    if (this.velocity < 0 && this.mesh.rotation.x != 0) {
        this.mesh.rotation.x += Math.abs(delta * this.speedUp * 0.5 * this.timeSpan);
        if (Math.abs(this.mesh.rotation.x - 2 * Math.PI) < 0.1) {
            this.mesh.rotation.x = 0;
        }
    }

    else {
        this.mesh.rotation.x += delta * this.velocity;

        this.time -= delta;
        this.velocity = this.speedUp * this.time;
    }
}

问题在于我无法想出一个解决方案或方法来完成我的主题。 如果变量delta不变,那就不会那么复杂了。
它应该 60fps = 1000/60左右,因为我正在使用requestAnimationFrame()

我还发现this question可以帮助找到解决方案。

我认为代码应该

  • 在达到实际结束之前减慢速度。
    如果最终角度略大于,则应该是这种情况。

  • 或者应该在达到实际结束后加快转速。
    如果最终角度比期望(开始)角度小,那应该是这种情况。

但是什么时候角度是一个偏离所需角度的半圆(即180°或PI)?

为了澄清我的问题,这是我的知识和未知数:

已知:

  • 开始速度
  • 时间间隔
  • 起始角度(通常为0)

我希望立方体在旋转结束时具有相同的起始角度/位置。 因为FPS计数不是常数,所以我必须缩短或延长时间间隔,以使立方体进入所需位置。

2 个答案:

答案 0 :(得分:1)

这是一种可能的方法,虽然它不如我想的那么好:http://jsfiddle.net/5NWab/8/

我们的想法是逐渐降低速度,就像你正在做的那样,根据剩余的时间,直到你到达立方体必须旋转到的距离的点。达到它的起始旋转(0)变为大于或等于在给定当前速度和当前剩余时间的情况下可能产生的旋转量。在此之后,忽略剩余时间,并按照左旋转量的比例减慢速度。

这适用于某些timeSpans,但对于其他人来说,结束减速动画需要一点时间。

答案 1 :(得分:1)

如果您希望旋转在特定时间以特定角度结束,那么我建议不要像当前代码(2012-09-27)那样连续递减旋转,而是设置目标时间和旋转时间初始化动画并计算帧重新计算时的正确旋转。

所以,如果你正在做一个正弦形的速度曲线(进出缓和,中间是线性的,很好的原生函数来计算它),那么(伪代码不使用你的变量):

//in init
var targetTime = now + animationTime;
// normalize the length of the sine curve
var timeFactor = pi/animationTime;
var startAngle = ...
var endAngle = ...
var angleChange = endAngle - startAngle;

// inside the animation, at some time t
var remainingT = targetTime - t;
if(remainingT <= 0) {
    var angle = endAngle;
} else {
    var angle = startAngle + cos(remainingT * timefactor) * angleChange;
}

[已编辑将startAngle添加到andle计算中]

因为cos函数是奇数(即关于原点对称),当t接近targetTime时,剩余的T接近零并且我们在曲线上从pi向后移动到0。 sin形状的曲线向零(和pi)变平,因此它会在结束时(在开头处)缓和。在targetTime处或之后存在明显的角度调零,因此帧速率中的任何抖动都不会不要把它推进无限循环。