0

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

我希望我的对象(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;
}

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

4

1 回答 1

2

下面的代码在功能上是相同的,只是使用三元组来压缩逻辑。IMO 它更容易阅读,但它完全是首选。

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''s 而不是 'if' 然后另一个 'if' 条件. 这是因为无论如何都会运行两个“if”条件,而在“if”/“else-if”中,如果“if”语句条件成功,则不会检查并跳过“else-if”条件,所以效率更高。

于 2016-10-02T19:06:35.983 回答