概要

表示可能な図形をいろいろ表示してみる。

@CretedDate 2013/08/19
@Versions Three.js r59

ShapeGeometry

ShapeGeometryはShapeで2Dの図形を描く。

<!DOCTYPE html>
<html>

<head>
  <meta charset='utf-8'> 
  <script src="three.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
  <script>
    $(document).ready( function() {
      // Rendererを用意
      renderer = new THREE.WebGLRenderer( { 'canvas' : $('#canvas')[0] } );
      renderer.setSize(300, 300);

      // Cameraを用意
      camera = new THREE.PerspectiveCamera();
      camera.position.z = 500;

      // Sceneを用意
      scene = new THREE.Scene();
      scene.add( camera );

      // 三角を作る
      var material = new THREE.MeshBasicMaterial( { color: 0xeeee00 } );
      var shape = new THREE.Shape();
      shape.moveTo(  0, 100 );
      shape.lineTo(  100, -50 );
      shape.lineTo( -100, -50 );
      shape.lineTo(  0, 100 );
      var geometry = new THREE.ShapeGeometry( shape );
      scene.add( new THREE.Mesh( geometry, material ) );

      // 描画
      renderer.render( scene, camera );
    } );
  </script>
</head>

<body>
  <canvas id="canvas" style="border:solid 1px; margin: 30px;">
    このブラウザは現在使われておりません。もう1度、Canvasに対応したブラウザで表示ください。
  </canvas>
</body>

</html>

レトロゲームを思い出す三角。

三角形

Line

Lineで中身を中をfillしない三角の線を引いてみる。

      // 三角の線を引く
      var material = new THREE.LineBasicMaterial( { linewidth: 5, color: 0xcccc00 } );
      var geometry = new THREE.Geometry();
      geometry.vertices.push(new THREE.Vector3(0, 100, 0));
      geometry.vertices.push(new THREE.Vector3(100, -50, 0));
      geometry.vertices.push(new THREE.Vector3(-100, -50, 0));
      geometry.vertices.push(new THREE.Vector3(0, 100, 0));
      scene.add( new THREE.Line( geometry, material ) );

三角形

CircleGeometry

CircleGeometryで頂点の数を指定して多角形を書く。とりあえず三角形から。

      var material = new THREE.MeshBasicMaterial( { color: 0xeeee00 } );
      var geometry = new THREE.CircleGeometry( 200, 3 );
      var mesh = new THREE.Mesh( geometry, material );
      scene.add( mesh );

傾きが気に入らない時は、3つ目の引数で調整。

      var material = new THREE.MeshBasicMaterial( { color: 0xeeee00 } );
      var geometry = new THREE.CircleGeometry( 200, 3, Math.PI / 2 );
      var mesh = new THREE.Mesh( geometry, material );
      scene.add( mesh );

頂点の数を増やして六角形にしてみる。

      var material = new THREE.MeshBasicMaterial( { color: 0xeeee00 } );
      var geometry = new THREE.CircleGeometry( 200, 6 );
      var mesh = new THREE.Mesh( geometry, material );
      scene.add( mesh );

頂点がたくさんになれば見た目は円になる。下記は500を設定。

      var material = new THREE.MeshBasicMaterial( { color: 0xeeee00 } );
      var geometry = new THREE.CircleGeometry( 200, 500 );
      var mesh = new THREE.Mesh( geometry, material );
      scene.add( mesh );

ConvexGeometry

ConvexGeometryは別途、ConvexGeometry.jsを呼んで使う。複数の頂点を渡してやると、それを繋いだ図形を描いてくれる。とりあえず4点で錐を。

      scene = new THREE.Scene();
      scene.add( camera );

      var points = [
        new THREE.Vector3( 0, -100, 100 ),
        new THREE.Vector3( 0, 100, 100 ),
        new THREE.Vector3( 100, -100, -100 ),
        new THREE.Vector3( -100, -100, -100 )
      ];

      var material = new THREE.MeshLambertMaterial( { color: 0x00eeaa } );
      var mesh = new THREE.Mesh( new THREE.ConvexGeometry( points ), material );
      scene.add( mesh );

      scene.add( mesh );

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

CubeGeometry

Cubeと言えばGameCube。引数は、幅、高さ、奥行きの順。その後に分割数も指定できる。分割数は Material の wireframe を true にするとわかりやすい。

      var material = new THREE.MeshBasicMaterial( { color: 0x008866, wireframe:true } );
      var mesh = new THREE.Mesh( new THREE.CubeGeometry( 200, 200, 200, 5, 5, 5 ), material );
      mesh.rotation.x = 0.5;
      mesh.rotation.y = 0.5;

分割数をそれぞれ5に指定したので、5マスずつに分割されたWireFrameが表示される。

CylinderGeometry

CylinderGeometryは、上の半径、下の半径、高さ、上下の分割、横の分割、蓋を閉じるかの6つの引数が指定できる。

Cylinder(円柱)とか言ってるけどデフォルトだと上辺底辺は八角形になる。

      var material = new THREE.MeshLambertMaterial( { color: 0x00aa88, wireframe:true } );
      var mesh = new THREE.Mesh( new THREE.CylinderGeometry( 50, 200, 150, 20, 0, false ), material );
      mesh.rotation.x = 0.7;
      mesh.rotation.y = 0.7;
      scene.add( mesh );

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

上辺底辺を20角形にしておいて、上の半径が50、下の半径が200、高さが150。とすると山みたいな図形になる。

IcosahedronGeometry

Icosahedronは20面体という意味。2個目の引数に1以上の数値を指定すると面の数が増える。

      var material = new THREE.MeshLambertMaterial( { color: 0x008866, wireframe:false } );
      var mesh = new THREE.Mesh( new THREE.IcosahedronGeometry( 200, 1 ), material );
      mesh.rotation.x = 1.2;
      mesh.rotation.y = 1.2;
      scene.add( mesh );

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

2個目の引数に1を指定した場合は、下図のようになる。

OctahedronGeometry

Octahedronなので八面体。

      var material = new THREE.MeshLambertMaterial( { color: 0x008866, wireframe:false } );
      var mesh = new THREE.Mesh( new THREE.OctahedronGeometry( 200 ), material );
      scene.add( mesh );

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

      controls = new THREE.TrackballControls( camera );

八面体を見てダイスを連想するかどうかでその人間の人となりが分かると言われている。

TetrahedronGeometry

Tetraということで四面体。

      var material = new THREE.MeshLambertMaterial( { color: 0x008866, wireframe:false } );
      var mesh = new THREE.Mesh( new THREE.TetrahedronGeometry( 200 ), material );
      scene.add( mesh );

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

TorusGeometry

Torusなので円環。引数は順に、半径、輪の幅、輪の分割、円の分割、弧の角。

      var material = new THREE.MeshLambertMaterial( { color: 0x008866, wireframe:false } );
      var mesh = new THREE.Mesh( new THREE.TorusGeometry( 200, 30, 20, 8, Math.PI * 1.9 ), material );
      scene.add( mesh );

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

半径200、幅30で途中でちょっと切れてる円環を描いてみた。

TorusKnotGeometry

Torus(円環)Knot(結び)。

引数は前4つはTorusGeometryと同じで、半径、輪の幅、輪の分割、円の分割。次の2つが結び目の数というか捻りというか。最後の1つが高さのScale。

      var material = new THREE.MeshLambertMaterial( { color: 0x008866, wireframe:false } );
      var mesh = new THREE.Mesh( new THREE.TorusKnotGeometry( 100, 30, 20, 8, 2, 5, 4 ), material );
      scene.add( mesh );

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

こんな感じになる。

SphereGeometry

球を書けるGeometryだけど、引数を変えるといろいろ書ける。前3つの引数は、半径、widthの分割、heightの分割。これで物体の形が決まる。デフォルトだとwidthが8、heigthが6の多面体が表示される。

後ろ4つの引数は、水平側の開始位置、長さ、垂直側の開始位置、長さ。適当にずらすと面白い図形ができあがる。

      var material = new THREE.MeshLambertMaterial( { color: 0x008866, wireframe:false } );
      var mesh = new THREE.Mesh( new THREE.SphereGeometry( 200, 8, 4, 0, Math.PI * 2, 0.5, Math.PI * 2 + 0.5 ), material );
      scene.add( mesh );

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

開始位置を適当にずらしてみたら、こんな風になった。

パラメトリック曲線

書き方はexamplesに入っているjs/geometriesを見るとわかりやすい。

とりあえず3/4の球を描いてみる。ParametricGeometryにそれっぽい関数を渡して描画する。

  <script src="three.js"></script>
  <script src="TrackballControls.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
  <script>
    var renderer, scene, camera, controls;

    function animate() {
      renderer.render( scene, camera );
      controls.update();
      requestAnimationFrame( animate );
    };

    $(document).ready( function() {
      // Rendererを用意
      renderer = new THREE.WebGLRenderer( { 'canvas' : $('#canvas')[0] } );
      renderer.setSize(300, 300);

      // Cameraを用意
      camera = new THREE.PerspectiveCamera();
      camera.position.z = 500;

      // Sceneを用意
      scene = new THREE.Scene();
      scene.add( camera );

      var func = function(u, v) {
        u *= Math.PI;
        v *= 1.5 * Math.PI;

        var x = 100 * Math.sin(u) * Math.cos(v);
        var y = 100 * Math.sin(u) * Math.sin(v);
        var z = 100 * Math.cos(u);

        return new THREE.Vector3(x, y, z);
      };
      var geometry = new THREE.ParametricGeometry(func, 100, 100, true);
      scene.add( new THREE.Mesh( geometry ) );

      controls = new THREE.TrackballControls( camera );

      // 描画
      animate();
    } );
  </script>

球の表面の位置をランダムで少し乱して、光を当ててみる。

      scene = new THREE.Scene();
      scene.add( camera );

      var func = function(u, v) {
        u *= Math.PI;
        v *= 2 * Math.PI;

        var x = 100 * Math.sin(u) * Math.cos(v);
        var y = 100 * Math.sin(u) * Math.sin(v);
        var z = 100 * Math.cos(u);
        x -= Math.random() * 50;
        y -= Math.random() * 50;
        z -= Math.random() * 50;

        return new THREE.Vector3(x, y, z);
      };
      var geometry = new THREE.ParametricGeometry(func, 100, 100, true);
      var material = new THREE.MeshLambertMaterial( { color: 0xffaa66 } );
      scene.add( new THREE.Mesh( geometry, material ) );

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

栗かタワシっぽい感じになった。

もう少しコネコネしてみる。

      var func = function(u, v) {
        u *= Math.PI;
        v *= 2 * Math.PI;

        var x = 100 * u - 100;
        var y = 100 * Math.sin(u) * Math.cos(v);
        var z = 100 * Math.cos(u);
        x -= Math.random() * 10;
        y -= Math.random() * 10;

        return new THREE.Vector3(x, y, z);
      };

葉っぱかな。

葉っぱじゃないよ、アヒ・・・を描こうとして3時間くらい格闘してみたけど、うまくいかず挫折。パラメトリック曲線でやることではなかった。

TextGeometry

Textを使う場合はその文字が収録されているjsファイルを持ってこないといけないので、けっこう面倒。

とりあえずexamples/fontsからアルファベットは読み込める。今回はhelvetiker_regular.typeface.jsを利用。

      var material = new THREE.MeshLambertMaterial( { color: 0x008866, wireframe:false } );
      var geometry = new THREE.TextGeometry( 'hello', { size: 100 });
      var mesh = new THREE.Mesh( geometry, material );
      mesh.position.set( -150, 0, 0 );
      scene.add( mesh );