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

标签 javascript math animation 3d three.js

我的场景中有一个立方体,我想以特定的起始速度给定的时间间隔 旋转它。
此外,立方体的结束 Angular 应与开始 Angular 相同。 因此,我想到允许时间间隔有±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 是常量,它就不会那么复杂。
它应该是 around 60fps = 1000/60 因为我正在使用 requestAnimationFrame()

我还找到了this question这有助于找到解决方案。

我认为代码应该要么

  • 在到达实际终点之前减慢速度。
    如果最终 Angular 稍微大于所需的(开始) Angular ,情况应该是这样。

  • 或者应该在到达实际终点后加快旋转速度。
    如果最终 Angular 稍微小于所需的(开始) Angular ,情况应该是这样。

但是,当 Angular 与所需 Angular (即 180° 或 PI)相差一个半圆时,情况又如何呢?

为了澄清我的问题,这里是我的已知和未知:

已知:

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

我希望立方体在旋转结束时具有相同的起始 Angular/位置。 由于 FPS 计数不是恒定的,我必须缩短或延长时间间隔才能使立方体到达所需位置。

最佳答案

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

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

//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)变平,因此它会在结束时缓和(并在开始时缓和)。在目标时间或超过目标时间时, Angular 会明确归零,因此帧速率中的任何抖动都不会'只是将其插入无限循环。

关于javascript - 在给定的时间间隔内创建平滑旋转 (+- x%),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12626750/

相关文章:

javascript - 好的示例/模板/最佳实践 API 文档

c++ - 为锦标赛系统分配奖品

algorithm - 非均匀圆盘的最佳覆盖

ios - 饼图动画完成事件

iphone - 以编程方式使用要设置动画的图像填充数组

javascript - 无法读取未定义的属性 'apply' - Youtube Api

javascript - jquery获取xml属性值,用\\转义不起作用

java - 增加或减少一个角度以最短的方式到达另一个角度

ios - 我如何在 viewDidLoad 中执行 UIView animateWithDuration? IOS 7

javascript - 如何将java脚本函数的返回值获取到在keyup上调用的变量