Three.js図解2: ジオメトリの比較

# はじめに
現在、[Three.jsの勉強中](https://qiita.com/skm_bnn/items/fe4c17ac65ce5c4a89db)です。その際に、詳細を調べていると、色々な描画スタイルが見つかります。この記事では、各スタイルを実際に比較して違いを理解していきたいと思います。

# ジオメトリの比較
今回の記事ではジオメトリの比較をしていきます。[この記事](https://qiita.com/skm_bnn/items/9bd86ab51a829efc43ef)にて、単純な立方体のアニメーションを描画しました。Three.jsでは立方体の他に様々な形状が用意されています。ここでは、1シーンで3つのジオメトリを比較していきます。

## ソースコードのひな形
次のソースコードを使用します。

### index.html
```html: index.html
<!DOCTYPE html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <title>Three.jsの図解2</title>
    <style>
      body {
        margin: 0;
      }
    </style>

    <!-- CDNからThree.jsのインポート -->
    <script type="importmap">
      {
        "imports": {
          "three": "https://unpkg.com/three@v0.159.0/build/three.module.js",
          "three/addons/": "https://unpkg.com/three@v0.159.0/examples/jsm/"
        }
      }
    </script>
  </head>

  <body>
    <!-- three.jsを使ったシーンのインポート -->
    <script type="module" src="./main.js"></script>
  </body>

</html>
```

### main.js
```描画オブジェクトの実装``` に注目してください。
```geometries``` 配列の宣言にある ```new THREE.ジオメトリ()``` の ```ジオメトリ``` という箇所を変更します。```ライトの実装``` については後日に改めてしっかりとまとめたいと思います。

```js: main.js (ひな形)
import * as THREE from 'three';

/* シーンの実装 */
const scene = new THREE.Scene();

/* カメラの実装 */
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);

/* レンダラーの実装 */
const renderer = new THREE.WebGLRenderer();               // インスタンスの生成
renderer.setSize(window.innerWidth, window.innerHeight);  // サイズの設定
document.body.appendChild(renderer.domElement);           // HTMLへの追加

/* ライトの実装 */
const color = 0xFFFFFF;                                     // 光の色
const intensity = 3;                                        // 光の強度
const light = new THREE.DirectionalLight(color, intensity); // ライトの生成
light.position.set(0, 0, 5);                                // ライトの配置
scene.add(light);                                           // シーンへの追加

/* 描画オブジェクトの実装 */
const geometries = [
  new THREE.ジオメトリ(),
  new THREE.ジオメトリ(),
  new THREE.ジオメトリ()
];
const material = new THREE.MeshLambertMaterial({ color: 0x00ff00 });  // マテリアルの生成
let obejects = [];

for (let i = 0; i < geometries.length; i++) {
  obejects.push(new THREE.Mesh(geometries[i], material)); // メッシュの生成
  scene.add(obejects[i]);                               // シーンへの追加
}

obejects[0].position.x = -3;
obejects[1].position.x = 0;
obejects[2].position.x = +3;

/* カメラの移動 */
camera.position.z = 5;

/* アニメーション関数の定義 */
function animate() {
  requestAnimationFrame(animate); // 定期的な関数呼び出し

  /* 回転するアニメーション処理 */
  for (let i = 0; i < geometries.length; i++) {
    obejects[i].rotation.x += 0.01;  // x軸方向
    obejects[i].rotation.y += 0.01;  // y軸方向
  }

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

animate(); // アニメーション関数の実行
```

## 比較1
次の動画にて、左に ```BoxGeometry``` 、中央に ```CapsuleGeometry``` 、右に ```CircleGeometry``` を示します。

![1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/bd5bd301-46d1-0d78-6c23-c76378790b9e.gif)


### ```BoxGeometry```
直方体を構成するジオメトリです。次に構文を示します。ポリゴンを区切る線のことをセグメントといいます。

```js: 
const ジオメトリ = new THREE.BoxGeometry(
  横幅,
  高さ,
  深さ,
  横幅セグメント,
  高さセグメント,
  深さセグメント
);
```
|引数|内容|デフォルト値|
|---|---|---|
|横幅|X軸と平行な辺の長さ|```1```|
|高さ|Y軸と平行な辺の長さ|```1```|
|深さ|Z軸と平行な辺の長さ|```1```|
|横幅セグメント|X軸と平行な面のセグメント数|```1```|
|高さセグメント|Y軸と平行な面のセグメント数|```1```|
|深さセグメント|Z軸と平行な面のセグメント数|```1```|

### ```CapsuleGeometry```
カプセル型の立体図形を構成するジオメトリです。次に構文を示します。

```js: 
const ジオメトリ = new THREE.CapsuleGeometry(
  半径,
  長さ,
  キャップセグメント,
  放射状セグメント
);
```
|引数|内容|デフォルト値|
|---|---|---|
|半径|カプセルの半径|```1```|
|長さ|中央にある多角柱の長さ|```1```|
|キャップセグメント|カプセルの曲面の滑らかさ|```4```|
|放射状セグメント|中央にある多角柱の頂点数|```8```|

### ```CircleGeometry```
円(多角形)の平面図形を構成するジオメトリです。次に構文を示します。

```js: 
const ジオメトリ = new THREE.CircleGeometry(
  半径,
  セグメント,
  始点角度,
  角度量
);
```
|引数|内容|デフォルト値|
|---|---|---|
|半径|円の半径|```1```|
|セグメント|円を構成するセグメント数(最小値: ```3```)|```32```|
|始点角度|円を描画し始める角度|```0```|
|角度量|描画する角度の量(円の中心角)|```2*PI```|

## 比較2
次の動画にて、左に ```ConeGeometry``` 、中央に ```CylinderGeometry``` 、右に ```DodecahedronGeometry``` を示します。

![2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/cc927861-3080-4497-3a7a-0c8ac75148cf.gif)


### ```ConeGeometry```
円錐(多角錐)の立体図形を構成するジオメトリです。次に構文を示します。

```js: 
const ジオメトリ = new THREE.ConeGeometry(
  半径,
  高さ,
  放射状セグメント, 
  高さセグメント,
  開封するか否か,
  始点角度,
  角度量
);
```

|引数|内容|デフォルト値|
|---|---|---|
|半径|底面の半径|```1```|
|高さ|円錐の高さ|```1```|
|放射状セグメント|中央にある多角柱の頂点数|```32```|
|高さセグメント|Y軸と平行な面のセグメント数|```1```|
|開封するか否か|底面を描画するか否か|```false```|
|始点角度|円を描画し始める角度|```0```|
|角度量|描画する角度の量(円の中心角)|```2*PI```|

### ```CylinderGeometry```
円柱(多角柱)の立体図形を構成するジオメトリです。次に構文を示します。

```js: 
const ジオメトリ = new THREE.CylinderGeometry(
  上面の半径,
  下面の半径,
  高さ,
  放射状セグメント, 
  高さセグメント,
  開封するか否か,
  始点角度,
  角度量
);
```

|引数|内容|デフォルト値|
|---|---|---|
|上面の半径|円柱の上面の半径|```1```|
|下面の半径|円柱の下面の半径|```1```|
|高さ|円柱の高さ|```1```|
|放射状セグメント|中央にある多角柱の頂点数|```32```|
|高さセグメント|Y軸と平行な面のセグメント数|```1```|
|開封するか否か|上面と底面を描画するか否か|```false```|
|始点角度|円を描画し始める角度|```0```|
|角度量|描画する角度の量(円の中心角)|```2*PI```|

### ```DodecahedronGeometry```
12面体の立体図形を構成するジオメトリです。次に構文を示します。

```js: 
const ジオメトリ = new THREE.DodecahedronGeometry(
  半径,
  詳細
);
```

|引数|内容|デフォルト値|
|---|---|---|
|半径|立体の半径|```1```|
|詳細|デフォルト値から増やすと12面体でなくなる|```0```|

# 参考
- シーンの作成

https://threejs.org/docs/#manual/en/introduction/Creating-a-scene

- BoxGeometry

https://threejs.org/docs/#api/en/geometries/BoxGeometry

- CapsuleGeometry

https://threejs.org/docs/#api/en/geometries/CapsuleGeometry

- CircleGeometry

https://threejs.org/docs/#api/en/geometries/CircleGeometry

-ConeGeometry

https://threejs.org/docs/#api/en/geometries/ConeGeometry

- CylinderGeometry

https://threejs.org/docs/#api/en/geometries/CylinderGeometry

- DodecahedronGeometry

https://threejs.org/docs/#api/en/geometries/DodecahedronGeometry