p5.jsにおける図形描画プログラムの生成ツール Shape Maker p5.js

# 1. 本記事について
p5.jsで図形を描画するプログラムの生成ツールを開発してみました。本記事では，その紹介および操作方法の説明をしていきます。本ツールは単純な操作で利用でき，オリジナルの描画関数を自動的にコーディングできることを目的として開発しました。

## 開発経緯
p5.jsはプログラミング初心者でも利用しやすいグラフィックスライブラリです。しかし，手軽に図形を描画する関数は [```rect()```](https://p5js.org/reference/#/p5/rect) や [```ellipse()```](https://p5js.org/reference/#/p5/ellipse) ，[```arc()```](https://p5js.org/reference/#/p5/arc) といった，長方形や楕円の類に限られます。[```triangle()```](https://p5js.org/reference/#/p5/triangle) や [```quad()```](https://p5js.org/reference/#/p5/quad) など，それ以外の描画関数では引数で頂点座標を指定する必要があります。さらに，大きさを自由に変更するには頂点の数だけ，その座標を変換する必要があります。

そこで，直感的に図形を描画することができ，なおかつ再利用しやすい描画関数を作成できるものがあれば便利であると思い，本ツールを開発しました。

# 2. Shape Maker p5.js
次のWebページに飛ぶことでツールを利用できます。

https://sakamo-bnn.github.io/ShapeMakerP5js/

![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/c716e698-e19b-6b92-7e54-4dc3cf12caeb.png)

# 3. 操作方法
Shape Maker p5.jsの操作方法を説明します。操作のほとんどがマウスクリックであるため，パソコン初心者でも利用できます。

## 操作(1) 頂点の定義
Webページ画面左にあるキャンバス上でマウスクリックをすると，そこに頂点として小さな円が表示されます。円の色について，赤色が最初に定義した頂点，青色が最後に定義した頂点を示します。また，黄色い斜めの正方形は図形の中央とする位置を示します。頂点の定義は3点以上してください。すなわち，キャンバス上のクリックは3回以上してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/3aa901fc-0bd1-f1c5-5384-b2422908e85b.png)
キャンバスの上下にあるボタンをクリックすることで，定義した頂点の操作ができます。
|ボタン|操作内容|
|---|---|
|頂点のクリア|定義した全ての頂点を消去する|
|←|最新の頂点を消去する(undo操作)|
|→|1つ前の操作を取り消す(redo操作)|

## 操作(2) 描画設定
Webページ画面右上の青色のボタンで図形の描画を設定することがあります。操作(1)の
キャンバス上にある図形で問題がない場合は，操作(3)に移ってください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/d550cabb-3b59-ca0b-ff37-288ffc3ff45a.png)

### 辺のスタイル
辺の様式を変更できます。
|設定|内容|
|---|---|
|直線|頂点を結ぶ線が直線になる|
|曲線|頂点を結ぶ線が曲線になる|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/5ea634c7-fe9f-1998-1117-3c6369834b92.png)

### 図形のスタイル
図形の辺を完全に閉じるか，終点で辺の描画を終えるか変更できます。
|設定|内容|
|---|---|
|CLOSE|始点と終点を結ぶ(デフォルト)|
|OPEN|始点と終点を結ばない|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/aba6567a-1775-3c62-821a-b2983b78dfb6.png)

### 中央位置の設定
図形の中央とする位置を設定します。
|設定|内容|
|---|---|
|重心|全ての頂点座標|
|原点|始点と終点を結ばない|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/892e42c6-f517-2961-f059-1b9031eb58a4.png)


## 操作(3) 描画関数プログラムの生成
Webページ画面右のテキストボックスに関数名を記入すると，描画関数のプログラムが生成されます。関数の引数は次の仕様となっています。 ```〇〇〇Mode(CENTER)``` における ```ellipse()``` や ```rect()``` と同じ構成です。なお，線や塗りつぶしのスタイルは ```stroke()``` や ```fill()``` など p5.js の関数で変更可能です。
|引数|内容|
|---|---|
|x|図形の中央位置のx座標|
|y|図形の中央位置のy座標|
|w|図形の幅|
|h|図形の高さ|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/99d8667a-321b-27f4-2d49-5183013b1966.png)
コピーボタンをクリックするとクリップボードにプログラムのテキストがコピーされるので，テキストエディタにペースト(Ctrl + V / ⌘ + V)すると関数を実装できます。Webページ画面右上から [p5.js Web Editor](https://editor.p5js.org/) や [OpenProcessing](https://openprocessing.org/) のページにジャンプできるので，お好みで活用ください。p5.js Web Editor では次のように利用できます。10行目以降でプログラムのペーストをしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/d5a813eb-1d66-3297-c11d-62ec9e29812c.png)

# 3. 使用例
次のシンプルなスケッチ sample1 をアレンジしてみます。

https://editor.p5js.org/sakamo_bnn/sketches/RV6RE2Zd0

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/fe3817dc-17fa-d3b0-cc56-c7896153502b.png)

## 手順(1) 描画関数の作成
本ツールを用いて，次のような図形を描く関数 ```ameba()``` を生成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/133ae1b2-182a-5c71-e972-073d09078d15.png)
生成された関数のプログラムを示します
```js: ameba()
function ameba (x, y, w, h){
  // 頂点座標の定義
  let v = [
    createVector(0.159, -0.272 ),
    createVector(0.093, -0.106 ),
    createVector(0.441, -0.073 ),
    createVector(0.276, 0.103 ),
    createVector(0.315, 0.46 ),
    createVector(0.087, 0.248 ),
    createVector(-0.035, 0.5 ),
    createVector(-0.095, 0.166 ),
    createVector(-0.397, 0.04 ),
    createVector(-0.186, -0.017 ),
    createVector(-0.5, -0.278 ),
    createVector(-0.126, -0.169 ),
    createVector(-0.055, -0.358 ),
    createVector(0.025, -0.245 )
  ];

  // 描画スタイルの設定
  push();
  translate(x, y);

  // 図形の描画
  beginShape();
  for (let i = 0; i < v.length; i++)
    curveVertex(v[i].x * w, v[i].y * h);
  for (let i = 0; i < 3; i++)
    curveVertex(v[i].x * w, v[i].y * h);
  endShape();

  // 描画スタイルの復元
  pop();
}
```

## 手順(2) スケッチへの実装
sample1 のプログラム末尾(17行目以降)に関数のプログラムをペーストします。そして，14行目の ```ellipse``` を ```ameba``` に置換します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/89aa0c16-bd2d-e882-58e4-4f74f4fdc4ec.png)

https://editor.p5js.org/sakamo_bnn/sketches/6GVpzjw0n

2行目で宣言した変数 ```layerNum``` の値を変更することで，さらに図形の数を増やせます。他にも描画関数 ```ameba()``` を自分で生成した関数に置き換えてみたり，```draw()``` 関数内で図形の座標や大きさを変更したりなど，あらゆる描画を試してみてください。

# 4. ソースコード
本ツールはReactを用いて開発しました。ソースコードはGithubで公開しています。

https://github.com/sakamo-bnn/ShapeMakerP5js

# 5. おわりに
長い記事となりましたが，ご閲読ありがとうございます。ツールに関するご質問やご意見がございましたら，コメントにてお問い合わせください。