【MATLAB】3次元形状データ（STLファイル）の扱いについて（読み込み・プロット）

# はじめに
　研究をやっていると、シミュレーション結果を3次元でプロットしたいときがあると思います。私の周りでも苦労している方がいるようです。私も昨年、MATLAB上でSTLファイルをインポートし、アニメーションを作りましたが苦労した記憶があります。シミュレーションの計算結果をアニメーションで見える化したいという需要はありそうなので、MATLABでのSTLモデルの扱い方についてまとめます。

### STLとは
　3次元データのファイルフォーマットの一つ。詳しいことは、Wiki参照

https://ja.wikipedia.org/wiki/Standard_Triangulated_Language

他にもOBJとかFBXとかある。3Dプリンターを使ったことがある人は、STL形式は馴染み深いと思います。

# 環境
MATLAB R2020b

# STLファイルをMATLABにインポートする
### データの準備
　まずはSTLファイルを用意します。私は[ここ](https://nasa3d.arc.nasa.gov/)から宇宙機の形状データをダウンロードしました。[カッシーニ](https://nasa3d.arc.nasa.gov/detail/jpl-vtad-cassini)にしました。ちなみに、windows 10 には、標準で3Dビューアーというソフトが入っているので、そのソフトを使用すれば3D形状を確認することができます。

### インポート
　MATLABへのインポートは、[stlread](https://jp.mathworks.com/help/matlab/ref/stlread.html)関数を使用します。`cassini.stl`をMATLABにインポートします。下記のコードではその後、`model` という構造体を作成しています。

```matlab
TR = stlread('cassini.stl');

model.Vertices = TR.Points;
model.Faces    = TR.ConnectivityList;
```

これにより、modelという3次元形状のデータが格納された構造体が作成されます。`model.Vertices`には各頂点の x, y, z 座標が、`model.Faces`にはどの頂点を結んで面を作成するか、という情報が入っています。


### プロット
　次に、3次元形状をプロットしてみます。プロットには、[patch](https://jp.mathworks.com/help/matlab/ref/patch.html?searchHighlight=patch&s_tid=srchtitle#d123e912161)関数を使用します。

```matlab
figure(1), clf
patch(model)
view([20 20])
```

出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001284/b40614cd-24f9-bc89-2250-62d2cef1ae96.png)

`view([20 20])`は、3次元プロットを見る角度を指定しています。形状の出力はできたけれど、真っ黒です。真っ黒なので、2次元に見えます。これは、パッチのプロパティをいじれば大丈夫です。`'FaceColor'`に色を設定します。

```matlab
figure(2), clf
patch(model, 'FaceColor', [0.8 0.8 1.0])
view([20 20])
```

出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001284/991bcdf2-cac9-bc09-418e-5edb16922700.png)

色が付きました。これで3次元に見えると思います。しかし、ポリゴンのエッジの線が表示されているので、黒くなっている部分もあります。これは、パッチの`'EdgeColor'`プロパティを設定することで、非表示にすることが可能です。

```matlab
figure(3), clf
patch(model, 'FaceColor', [0.8 0.8 1.0], ...
    'EdgeColor', 'none')
view([20 20])
```

出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001284/64a48463-1fb4-213f-ffbb-f6943186fa1c.png)

エッジの線は消えましたが、また2次元に見えるようになってしまいました。ここに光源の設定をすることで、凹凸がわかる3次元形状のプロットが完成します。見た目をリアルにするために、パッチのプロパティも少し変更を加えます。

```matlab
figure(4), clf
patch(model, 'FaceColor', [0.8 0.8 1.0], ...
    'EdgeColor', 'none', ...
    'FaceLighting', 'gouraud', ...
    'AmbientStrength', 0.15)
view([20 20])
lightangle(-45,70)
```
出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001284/04c53a62-cdda-dd22-2f12-929eb97f0604.png)

これは感動ですね。しかし、まだ問題点があります。ウィンドウのサイズを変えてしまうと、プロットの軸のサイズも合わせて変わってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001284/55b5769b-3c58-7808-d178-fa873b459d0a.png)

この問題点は、軸の比を設定すれば解決できます。下記のコードが完成形です。

```matlab
figure(5), clf
patch(model, 'FaceColor', [0.8 0.8 1.0], ...
    'EdgeColor', 'none', ...
    'FaceLighting', 'gouraud', ...
    'AmbientStrength', 0.15)
view([20 20])
lightangle(-45,70)
set(gca, 'DataAspectRatio',[1 1 1])
```

これで、ウィンドウのサイズを変更すると、軸のサイズも動的に変更されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001284/24fa8ccd-0966-1234-36e3-8eea64c26f68.png)

完成。


# おわりに
　これで、STLファイルをMATLABにインポートし、プロットをすることができます。FaceColorの値を変更すれば、好みの色にすることもできます。ここからアニメーションを作成するには、物体の頂点の座標に手を加えればよいです。これについては後日書きます。