2016-10-02 109 views
0

我刚写了一段代码来处理THREE.js场景中的对象旋转。但问题不是3D特定的。JavaScript - 动画旋转算法

我希望我的对象(this)在每个函数调用时转过0.25弧度,直到旋转(this.clientRotation)达到this.targetRotation中定义的旋转。下面的代码是update()函数的内容,它在渲染循环中被连续调用。

我不得不检查当前旋转和目标旋转之间的绝对差值是否高于每次调用的旋转量(0.25),以避免在目标旋转几乎到达时来回旋转。

我不得不检查旋转(以弧度表示)的差异是否超过180度,在这种情况下,最短的转弯是相反的。

我必须检查更新后的旋转是否保持在-PI和+ PI(0和360度)之间。

//Move only if we find a delta big enough between the target rotation and current rotation 
//Rotation goes from -PI to +PI 
this.rotationSpeed = 0.25; 

var absDiff = Math.abs(this.clientRotation - this.targetRotation); 
if(absDiff > this.rotationSpeed){ 

    if(absDiff < Math.PI){ 

    //Less than 180 degrees, turn towards the target 
    if(this.targetRotation > this.clientRotation) this.clientRotation += this.rotationSpeed; 
    if(this.targetRotation < this.clientRotation) this.clientRotation -= this.rotationSpeed; 
    } else { 

    //More than 180 degrees this way, so it is shorter to turn the other way 
    if(this.targetRotation > this.clientRotation) this.clientRotation -= this.rotationSpeed; 
    if(this.targetRotation < this.clientRotation) this.clientRotation += this.rotationSpeed; 
    } 

    //If rotation radians becomes more than a complete 360 turn, start again from 0 
//If it goes below 0, start again down from 360 
    if(this.clientRotation > Math.PI) this.clientRotation -= Math.PI*2; 
    if(this.clientRotation < -Math.PI) this.clientRotation += Math.PI*2; 
} 

它的作品,但它似乎过于复杂。有没有更优化的方式来实现这种标准的旋转行为?

回答

2

下面的代码在功能上是相同的,只是使用三元来浓缩逻辑。海事组织阅读起来要容易得多,但它完全偏爱。

this.rotationSpeed = 0.25; 
var absDiff = Math.abs(this.clientRotation - this.targetRotation); 
if(absDiff > this.rotationSpeed) { 
    var lessThan180 = absDiff < Math.PI; 
    if(this.targetRotation > this.clientRotation) { 
    this.clientRotation = (lessThan180) ? this.clientRotation + this.rotationSpeed : this.clientRotation - this.rotationSpeed; 
    } else if (this.targetRotation < this.clientRotation) { 
    this.clientRotation = (lessThan180) ? this.clientRotation - this.RotationSpeed : this.clientRotation + this.rotationSpeed; 
    } 
    this.clientRotation = (this.clientRotation > Math.PI) ? this.clientRotation - Math.PI*2 : this.clientRotation + Math.PI*2; 
} 

你原来的代码可能看起来过于复杂,但其实我觉得你做的非常出色记录,通过注释你的代码,使代码清晰可读。我建议改变的唯一挑剔的事情,不管是什么(即使你不是三星的粉丝),都是使用'if'/'else-if'而不是'if',那么另一个'if'条件。这是因为'if'条件无论如何都会被运行,而'if'/'else-if'如果'if'语句条件成功,则'else-if'条件不会被检查并跳过,所以它更有效率。

+0

我也经常使用三元组,但是我个人发现在某些情况下没有它们的代码更清晰。其他的好点 - 如果:) – Rayjax