2016-10-02 8 views
0

THREE.jsシーンでオブジェクトの回転を処理するコードを書きました。しかし問題は3D特有ではありません。JavaScript - アニメーション回転アルゴリズム

私のオブジェクト(this)は、回転(this.clientRotation)がthis.targetRotationで定義された回転に達するまで、各関数呼び出し時に0.25ラジアン回転します。以下のコードは、レンダリングループで継続的に呼び出される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

以下のコードは機能的には、論理を凝縮するために3値を使用するだけで同じです。 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; 
} 

あなたの元のコードは複雑な上に見えるかもしれませんが、私は実際にあなたがコメントを通して、あなたのコードを文書化し、コードが明確で読みやすく素晴らしい仕事をしたと思います。私が変更をお勧めする唯一のニックピットyのものは、(たとえあなたが三者のファンではないにしても) 'if'/'else-if'の代わりに 'if'を使用し、 'if'条件付き。これは、 'if'文が条件に合致していれば、 'if'/'else-if'の 'if'文が成功すれば 'else-if'条件はチェックされずにスキップされるからです、より効率的です。

+0

私はしばしば3進数を使っていますが、私は個人的には、それらがなくても明確なコードを見つけることがあります。 else-ifsのための良い点:) – Rayjax

関連する問題