14

太陽系の縮尺模型を作ろうとしています。回転速度がどのように機能するかを誰かが説明してくれるかどうか知りたかった. 重要な部分は次のとおりです。

objects[index].rotation.y += calculateRotationSpeed(value.radius,value.revolution) * delta;

回転速度と実際の時間の関係は? では、速度が 1 の場合、それは 1 ミリ秒あたり 1 ピクセルの動きですか? または、速度が 0.1 の場合、それは 1 秒あたり 1 ピクセル未満ですか?

基本的に、惑星の半径と 1 日の時間数を考慮して、惑星の正しい回転速度を計算しようとしています。地球なら24時間で1回転します。これが私が書いた関数で、現在計算を行っています:

/* In a day */
function calculateRotationSpeed(radius,hrs,delta) {
    var cir = findCircumference(radius);
    if(delta) {
        var d = delta;
    } else {
        var d = 1;
    }
    var ms = hrs2ms(hrs) * d;
    var pxPerMS = km2px(cir) / ms;
    return pxPerMS;
}

試してみましたが、まだ動きが速すぎるようです。また、軌道速度を計算するために同様のものが必要です。

4

1 に答える 1

70

回転と単位

Three.JS の回転はラジアンで測定されます。ラジアンにまったく慣れていない人のために(私の古い論文からの小さな抜粋):

数学定数Piと同様に、ラジアン(約 57.3 度) は、円の半径 (または直径) とその円周との関係から導き出されます。1 ラジアンは長さが同じ円の半径に等しい円の円周上の円弧にまたがる角度です (サイズに関係なく、どの円にも当てはまります)。同様に、Pi は直径に対する円周の比率であり、単位円の円周は正確に P​​i です。ラジアンと度は実際には真の単位ではありません。実際、角度は一般に無次元です (パーセンテージや分数のように、実際の単位を使用して記述することはありません)。

ただし、度数とは異なり、ラジアンは任意に定義されたものではないため、ほとんどの場合、より自然な選択になります。多くの場合、数式で度を使用するよりもはるかに簡単で、はるかにエレガントで、明確で、簡潔です。バビロニア人はおそらく、円を 6 つの等しいセクションに分割して (正三角形の角度を使用して) 度を与えました。これらの 6 つのセクションのそれぞれは、60 進数(基数 60) の数体系を考えると、おそらくさらに 60 の等しい部分に細分化されました。これにより、天文学にそのようなシステムを使用することも可能になります.1年の推定日数は、当時ははるかに正確ではなく、多くの場合360と見なされていたためです.

Three.JS の基本的なローテーション

したがって、ラジアンで作業していることがわかったので、次のステートメントの最初のステートメントを関数 ( へのコールバック) で1 回使用してインクリメントすると、x 軸上のの回転が 1 ラジアンずつインクリメントされます。animrequestAnimFramemesh

mesh.rotation.x += 1;                      // Rotates   1 radian  per frame
mesh.rotation.x += Math.PI / 180;          // Rotates   1 degree  per frame
mesh.rotation.x += 45 * Math.PI / 180      // Rotates  45 degrees per frame

上記のステートメントの最後の 2 つが示すようにMath.PI / 180代わりに度を使用したい場合は、代入の前に度の値をラジアンに簡単に変換するために使用できます。

フレームレートを考慮する

あなたの場合、各フレームでどれだけの時間が経過するかを考慮する必要があります。これはあなたのdeltaです。次のように考える必要があります。実行している FPS の数は? 必要な情報へのインターフェースを持つオブジェクトをclock格納するグローバル変数を宣言します。THREE.Clock呼び出すグローバル変数が必要ですclock(他の関数、特に でアクセスできる必要がありますanim):

initで、のインスタンスを作成しますTHREE.Clock。外部で宣言された変数に格納しますinit(より大きなスコープで):

clock = new THREE.Clock();

次に、anim関数内で、 に関連付けられた 2 つの変数を更新する 2 つの呼び出しを行いますclock

  • time(クロックがインスタンス化されてからの合計経過時間 (ミリ秒))
  • delta(各フレーム間のミリ秒単位の時間) は、他の 2 つのグローバル変数で:
時間 = clock.getElapsedTime();
 デルタ = clock.getDelta();

各フレーム間の時間を返すためのものでdeltaあることに注意してください。ただし、これは、/内で一貫して呼び出される場合にのみtrue になります。clock.getDeltaanimrender

  1. アニメーション/レンダリング サイクルごとに 1 回のみ
  2. 各アニメーション サイクルの同じ場所 (開始または終了、私の知る限り、どちらが重要ではない)

上記の条件はTHREE.Clock実装の結果です。getDelta最初はクロックがインスタンス化されてからの時間を返しますが、その後返される時間は単に最後に呼び出されてからの時間です)。どういうわけか間違って、または一貫性を欠いて呼び出されると、物事が台無しになります。

デルタ係数による回転

シーンがプロセッサまたは GPU の速度を落とさない場合、Three.JS とそれに含まれているrequestAnimationFrame shimは、(利用可能なリソースを使用して) スムーズな 60 フレーム/秒で動作を維持しようとします。これは、理想的には1/60 = .016666、各フレームの間に約秒があることを意味します。これはdelta、各フレームから読み取ることができる値であり、clock以下に示すように乗算することにより、フレームレートに基づいて速度を正規化するために使用できます。このようにして、秒単位の値を取得するために毎回乗算できるフレームレートの小さな変動に関係なく、秒単位の値を取得できます。

したがって、関数の最初に持っていたものに基づいて、次のanimように使用できます。

mesh.rotation.x += delta * 1;                     // Rotates  1 radian  per second
mesh.rotation.x += delta * Math.PI / 180;         // Rotates  1 degree  per second
mesh.rotation.x += delta * 45 * Math.PI / 180;    // Rotates 45 degrees per second

回転速度と単位

角度、ラジアン、度の測定は実際には単位ではないため、角速度の単位を見ると、時間のみの関数であることがわかります (あなたが持っているような距離と時間の関数としてではなく)コード)。

時間に基づく回転速度の計算

特定のケースについては、回転速度(角速度)を計算するために半径は必要ありません。代わりに、1日の時間数(完全な回転にかかる時間、つまり2 * Math.PI ラジアンのラジアン)を使用できます。その軸の回転)。という変数がある場合は、revolutionTimeそのように計算できます。

secondsInAnHour = 3600;
rotationalSpeed = (2 * Math.PI) / revolutionTime;

地球が1日であると仮定すると24 hours = 24 * 60 * 60 = 86,400(そうではありません)。次にrotationalSpeed = 2 * PI / 86,400、 、またはおよそ0.0000727 1 秒あたりのラジアンを取得します。これよりも正確な教科書の値を見つけることができるはずです (地球が 1 回転を完了するのにかかる時間の 24 時間フラット図よりも正確な測定値を考慮に入れると.

あなたのケースを特に考慮する

ただし、惑星のすべての角速度が正確に正確であることを確認することについては心配しません。代わりに、(惑星の)各角速度間の比率を計算し、それを使用することをお勧めします。これはいくつかの理由でうまく機能します: より速い回転速度が必要になる可能性があります。重要なことは、他のモデルと同様 (特に天文モデルの場合)、スケールを維持することです。

于 2012-07-06T15:04:07.043 に答える