プログラミング/JavaScript/three.js

(1814d) 更新

公開メモ

ブラウザ上に JavaScript から3D表示するためのライブラリ

http://threejs.org/ から落として来られます。

データの可視化などに便利に使えそう。

以下はメモ

THREE.CylinderGeometry で作った Cylinder を任意のベクトル方向に向ける

THREE.CylinderGeometry で作った Cylinder は、そのままだと原点を中心として y 軸方向を向くのですが、これを原点から始まる任意のベクトルに沿った位置に 回転・移動するには、たぶん以下のようにして THREE.Quaternion を使うのが楽そう?です。

THREE.object3d.up の意味などがよく分かっていないので何なのですが・・・

LANG:javascript
///
// src: Vector3
// dest: Vector3
// src.normalize() を dest.normalize() に変換する回転を表わす quaternion を作成する
//
THREE.Quaternion.prototype.fromVectors = function(src, dest) {
    var nsrc  = src.clone().normalize();
    var ndest = dest.clone().normalize();
    var cos = nsrc.dot(ndest);
    var axis = ndest.clone().cross(nsrc);
    var sin = axis.length();
    return this.setFromAxisAngle(axis.normalize(), Math.atan2(-sin, cos));
};

///
// v: Vector3 にと同じ長さ・同じ向きを持った Cylindrical Mesh を作成する
function createCylinderAlong(v, geometry, material) {
    var mesh = new THREE.Mesh( geometry, material );
    mesh.scale.y = v.length();                                  // 長さを合わせる
    mesh.useQuaternion = true;
    mesh.quaternion.fromVectors(new THREE.Vector3(0,1,0), v);   // 向きを合わせる
    mesh.position = v.clone().multiplyScalar(0.5);              // 中心をずらす
    return mesh;
}

使用例

LANG:html
<!DOCTYPE html>
<html>
    <head>
        <title>rotation test</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                color: #000;
                background-color: #000;
                margin: 0px;
                overflow: hidden;
            }
        </style>
    </head>

    <body>
        <div id="container"></div>

        <script src="three.min.js"></script>

        <script>
            var container;
            var camera, controls, scene, renderer;
            var cross;

            function init() {

                camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
                camera.position.z = 5;

                scene = new THREE.Scene();

                // v 方向を向く Cylinder

                var v = new THREE.Vector3(-4,+2,-5);
               
                var geometryCylinder = new THREE.CylinderGeometry(0, 0.1, 1, 20, 1, false);
                var materialCylinder = new THREE.MeshLambertMaterial( { color: 0x00ffff } );
                var mesh = createCylinderAlong(v, geometryCylinder, materialCylinder);
                scene.add( mesh );
                
                // 向き&位置確認用の小球
                particle = new THREE.Mesh(
                         new THREE.SphereGeometry(0.1, 20, 10),
                         new THREE.MeshLambertMaterial( { color: 0x00ffff } )
                     );
                particle.position=v;
                scene.add( particle );

                // lights

                light = new THREE.DirectionalLight( 0xffffff );
                light.position.set( 1, 1, 1 );
                scene.add( light );

                light = new THREE.DirectionalLight( 0x002288 );
                light.position.set( -1, -1, -1 );
                scene.add( light );

                light = new THREE.AmbientLight( 0x666666 );
                scene.add( light );

                // renderer

                renderer = new THREE.WebGLRenderer( { antialias: true } );
                renderer.setSize( window.innerWidth, window.innerHeight );

                container = document.getElementById( 'container' );
                container.appendChild( renderer.domElement );

                window.addEventListener( 'resize', onWindowResize, false );

            }

            function onWindowResize() {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize( window.innerWidth, window.innerHeight );
                render();
            }

            function render() {
                renderer.render( scene, camera );
            }
            
            init();
            render();

        </script>

    </body>
</html>

cylinder.PNG


添付ファイル: filecylinder.PNG 260件 [詳細]

Counter: 1345 (from 2010/06/03), today: 1, yesterday: 1