2016年4月28日木曜日

Three.jsでコマをつくる

Three.jsでコマのような動きを再現してみたので、そのときの手順をまとめる。具体的には、平面(床)と三角錐(コマ)を作成し、三角錐を回転させる。

1.オブジェクトの作成
床の作成にはTHREE.PlaneGeometry、コマの作成にはTHREE.CylinderGeometryを使用する。THREE.CylinderGeometryの第1か第2引数を0にすると三角錐になる。以下は床とコマを作成して床の傾きとカメラ位置を調整するコード。
// シーンの作成
var scene = new THREE.Scene();
// カメラの作成
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
// レンダラーの作成
var renderer = new THREE.WebGLRenderer();
// レンダラーが描画するキャンバスサイズの設定
renderer.setSize( window.innerWidth, window.innerHeight );
// キャンバスをDOMツリーに追加
document.body.appendChild( renderer.domElement );

// 光源の作成
var light = new THREE.DirectionalLight( 0xffffff );
// 光源の位置調整
light.position.set( 0, -1, 1 ).normalize();
// 光源をシーンに追加
scene.add( light );

// 床の作成
var plane = new THREE.Mesh( new THREE.PlaneGeometry( 5, 5), new THREE.MeshBasicMaterial( { color: 0x0000ff} ) );
// 床の傾き調整
plane.rotation.x = -Math.PI/8;
// 床をシーンに追加
scene.add( plane );

// コマのジオメトリ作成
// CylinderGeometryの第1か第2引数を0にすると三角錐になる
var geometry = new THREE.CylinderGeometry( 0, 2, 3, 32, 32 );
// コマのマテリアル作成
var material = new THREE.MeshPhongMaterial( {color: 0xffff00} );
// コマのオブジェクト作成
var spinning = new THREE.Mesh( geometry, material );
// コマをシーンに追加
scene.add( spinning );

// カメラ位置設定
camera.position.z = 6;
camera.position.x = -1;
camera.position.y = -2;

上記コードだと床とコマは以下のような位置関係になる。


2.コマを床の上に立たせる
床とコマの位置関係を、コマが床の上に接して立っているように調整する。それにはコマを床に対して90度傾けて床に先端が向くようにして、先端が床に接するように位置をずらす。90度傾けるのはX軸に対してなので、コマ先端と床のずれはY-Z座標上で調整する。先端と床までの距離は三角関数を利用して計算する。床の傾き角度をθとすると、以下の式で求められる。

y = 三角錐の高さ/2 × sinθ
z = 三角錐の高さ/2 × cosθ

// コマの位置調整(床に対して先端方向が垂直になるように)
spinning.rotation.x = -Math.PI*5/8;
spinning.position.y = 1.5 * Math.sin( Math.PI/8 );
spinning.position.z = 1.5 * Math.cos( Math.PI/8 );

以下のようになる。


3.コマを回転させる
コマの回転にはObject.rotateOnAxisを使う。これはオブジェクト上の座標で指定した軸に対してオブジェクトを回転させる。コマの回転軸はY軸。
// コマの回転軸ベクトル
var axis = new THREE.Vector3(0,1,0);

function render(){
// requestAnimationFrameで自分自身を呼び出し続けることでレンダリングを繰り返す
requestAnimationFrame( render );

// コマの回転
spinning.rotateOnAxis (axis, Math.PI/100);

// レンダリング(表示)
renderer.render(scene,camera);
}
render();

これでコマが床の上で回転する。

0 件のコメント:

コメントを投稿