cube_korokoro


立方体を転がす

 台の上で、立方体を転がしてみます。
 タイヤのような丸い物体ではないので、立方体が転がるアニメーションは、少し複雑かもしれませんね。


単純に回転すると?

 単純に、立方体の中心で回転させると、下図のような感じになって、立方体の角が地面にめり込んでしまいます。

koro1

 コロコロ転がると聞くと、イメージはこっち(下図)ですよね?

koro2

 いくつか方法がありそうです。立方体の中心で回転させながら、中心座標の軌跡を計算して動かす方法とか。中心座標の軌跡はたぶん、円弧の一部ですね。Xi-TRACEは、数値演算しながら物体の定義ができるので、この方法でもOKですが、今回は、中心座標の軌跡を計算せず、回転と平行移動だけを使って立方体を転がしてみます。


転がり方を整理

 転がり方を整理してみます(下図)。

koro3

 簡単化のため、直方体を真横から見て四角形で表現しています。四角形ABCDが図の右方向へ転がろうとしています。この場合、回転の中心、軸となるのは、赤く印をつけたA点です。A点を軸に90°回転すると、AB'C'D'の位置に四角形が移動します。
 ここで注意したいのは、90°回転する間、四角形の中心E点や点B,C,Dは動いていますが、回転の軸であるA点は動いていません。
 90°回転し終わった時、ちょうど四角形の一辺の長さ分だけ、図の右側に四角形が動いています。
 次の回転はどうでしょうか?今度は、四角形AB'C'D'が点D'を軸として、90°回転します。回転軸がA点からD'点に移りますが、動作は同じです。
 整理してみると、

  1. 回転軸を中心とした90°の回転
  2. 90°回転する度に横方向へ一辺の長さだけ移動
  3. 90°回転する度に回転軸がA点→D'点へ移動

 こんな感じでしょうか?90°回転中の連続的な動きであるNo.1と、90°回転毎に発生する不連続な動きであるNo.2、3の合成ですね。

連続的な動き

1. 回転軸を中心とした90°の回転

 No.1の動きについて、記述を抜き出してみます(関係のある定数の設定なども抜き出しています)。

  var fn_rot=30;
  var fn_tot=fn_rot*6;
  para cr,0,0;
  roty 90*(fn%fn_rot)/fn_rot;
  para -cr,0,0;


 どうやら、90°の回転を1つの単位として考えた方がわかりやすそうですので、90°回転に費やすフレーム数をfn_rotという変数で定義しました。この例では、fn_rot=30ですので、30フレームかけて90°の回転が実行されます。もし、アニメーションを30FPS(Frames Per Second)で再生したなら、1秒で90°回転する計算です。
 あとは、90°回転の繰り返しですので、その6回分をfn_totとして定義し、計180(=30×6)フレームのアニメーションを作成します。
 肝心の回転ですが、rotyを使い、y軸の周りに回転させています。フレーム番号fnは、0〜179までカウントしていきますので、fn_rotで剰余(%)を取り、一回の90°回転のインデックス値を計算しています。

  fn%fn_rot : 0〜fn_rot-1 までの値をとる
  (fn%fn_rot)/fn_rot : 0〜1までの値をとる(ただし、1にはならない、最大で(fn_rot-1)/fn_rot)
  90*(fn%fn_rot)/fn_rot : 0〜90までの値をとる(同様に90にはならない)

 それをfn_rotで割り算して、90を掛けることで、0〜90の回転角度を得ています。
 rotyは、回転軸がy軸なので、A点に示した回転軸をy軸に一致させておかなくてはなりません。この調整をしているのが、rotyを上下に挟んでいるpara(平行移動)命令です。para -cr,0,0で、A点をy軸に一致させ、rotyで回転、終わったらpara cr,0,0で元の位置に戻す。一次変換の記述順と変換順に関しては、マニュアルを見てくださいね。

不連続な動き

2. 90°回転する度に横方向へ一辺の長さだけ移動

 関連する記述を抜き出してみます。

  // fn_rot毎に立方体一辺(2*cr)分移動させる。
  para -fn_tot/fn_rot/2*2*cr + int (fn/fn_rot)*2*cr,0,0;


 立方体の移動(転がる)方向はx軸方向ですので、para命令の第一パラメータが移動量です。

  -fn_tot/fn_rot/2*2*cr + int (fn/fn_rot)*2*cr

 変数crには、立方体の一辺の長さの1/2が代入されており、2*crは一辺の長さです。数式の前半はfn_tot、fn_rot、crで決まっており、全フレームを通して定数です。「動き」には関係なく、物体の位置を決めているパラメータです。
 数式の後半、int (fn/fn_rot)*2*crの部分が不連続な動きを作り出している部分です。2*crは一辺の長さで定数ですので、int (〜)の部分ですね。int()関数は、引数を「その値を超えない最大の正数」に変換します。引数は、フレーム番号fnを90°回転させるのに費やすフレーム数fn_rotで割り算していますので、以下のようになります。

  fn=0〜fn_rot-1 : int (fn/fn_rot)=0
  fn=fn_rot〜fn_rot*2-1 : int (fn/fn_rot)=1
  fn=fn_rot*2〜fn_rot*3-1 : int (fn/fn_rot)=2
  fn=fn_rot*3〜fn_rot*4-1 : int (fn/fn_rot)=3
  fn=fn_rot*4〜fn_rot*5-1 : int (fn/fn_rot)=4

 90°回転(fn_rot)毎に、0 → 1 → 2 →……と、増加して行きます。

3. 90°回転する度に回転軸がA点→D'点へ移動

 関連する記述は以下です。

  roty int (fn/fn_rot)*90;

 int()関数の部分はNo.2で説明した通りです。その値に90を掛け算していますので、fn_rot毎に90°回転することとなり、A点の位置にD'点が移動してきます。


検証

 完成したデータと動画をご覧に入れます。

  Xi-TRACEデータ:cube_korokoro.xitr



 「手抜きなしでちゃんと回転させていますよ」というアピールのため、立方体の側面に"F"の文字をマッピングしました。オーバレイマッピング機能を使って、Fの文字は不透明ですが、それ以外の場所は赤の透明にしてあります。


home

download

gallery