p5.jsの関数まとめ part.12 rotate()

この記事は Qiita p5js アドベントカレンダー17日目の記事です。

## これはなに
p5.jsが用意している関数について理解を深める記事です。
今回は回す関数、rotate()について。

## rotate()
物体を回転させる機能を持つ関数です。
引数を動的なものにすることによって、物体も持続的に回転しているように見せることができます。

### リファレンスより
> angleパラメータで指定された量だけ、図形を回転させる。この関数はangleModeを考慮するので、角度はRADIANSまたはDEGREESで入力することができます。オブジェクトは常に原点を中心とした相対位置で回転し、正の数はオブジェクトを時計回り方向に回転させます。変換は、その後に起こるすべてのことに適用され、その後にこの関数を呼び出すと、その効果が蓄積されます。例えば、rotate(HALF_PI) を呼び出した後に rotate(HALF_PI) を呼び出すと rotate(PI) と同じになります。すべての変換は、draw()が再び開始されたときにリセットされます。技術的には、rotate() は、現在の変換行列と回転行列を掛け合わせます。この関数はさらに push() と pop() で制御することができます。（DeepL翻訳）

**変換は、その後に起こるすべてのことに適用され、その後にこの関数を呼び出すと、その効果が蓄積されます。**
このへんは注意したいところですね。次の項目で検証することにします。

では実際にrotate()の挙動を試してみましょう。

白の正方形を中心に置き、rotateにPIを渡してみます。

```javascript
function setup() {
  createCanvas(600, 600);	
  background(0)
  noStroke()
}

function draw() {
  fill('white')
  translate(width / 2, height / 2)
  rotate(PI)
  rect(-100, -100, 200, 200)
}
```
![スクリーンショット 2021-12-16 11.18.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358229/ebd61acf-c2ae-f237-6dcd-454f1ffefa18.png)


あれ、なにも変わらない。。と思いきやPIは180度なので正方形の場合変わらないように見えます。
PIを90の倍数にならないように割ってあげましょう(足してもかけてもなんでもOK)。
`PI / 3`を渡してあげて、text()で引数の中身も表示してみます。

```javascript
function draw() {
  fill('white')
  translate(width / 2, height / 2)
  rotate(PI / 3) // 3で割る
  rect(-100, -100, 200, 200)
  
  fill('red')
  textSize(32);
  text(PI / 3, 100, 100) // 引数の中身を表示
}
```

![スクリーンショット 2021-12-16 11.27.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358229/e3eaf77a-b969-a46f-c0a7-c25c8031f1f7.png)


おーちゃんと60度回転して表示されました。
よくみると表示している文字もrotate()の影響で60度回転していることが分かります。
「文字は普通に表示したい！」という時は[push()とpop()](https://qiita.com/shibuya01055/items/76c72d85f6aa0dab32c5)を使いましょう。

```javascript
fill('white')
translate(width / 2, height / 2)

push()
rotate(PI / 3) // 3で割る
rect(-100, -100, 200, 200)
pop()

fill('red')
textSize(32);
text(PI / 3, 100, 100) // 引数の中身を表示
```

![スクリーンショット 2021-12-16 11.33.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358229/352e6fb7-e8fb-c297-bb5d-34211e397e6f.png)



### 蓄積について
先ほどのコードに次のコードを何回か足していきます。

```javascript
rotate(PI / 3)
text(PI / 3, 100, 100)
```

するとこのように描画されました。

```javascript
fill('white')
translate(width / 2, height / 2)

rotate(PI / 3) // 3で割る
rect(-100, -100, 200, 200)

fill('red')
textSize(32);
rotate(PI / 3)
text(PI / 3, 100, 100) // 引数の中身を表示

rotate(PI / 3)
text(PI / 3, 100, 100)

rotate(PI / 3)
text(PI / 3, 100, 100)

rotate(PI / 3)
text(PI / 3, 100, 100)

rotate(PI / 3)
text(PI / 3, 100, 100)

rotate(PI / 3)
text(PI / 3, 100, 100)
```

![スクリーンショット 2021-12-16 11.42.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358229/33a7e961-e0ee-093e-da7c-2d44e35f3b59.png)

canvas下部の文字は60度回転しています。
そこから`rotate(PI / 3)`で次の文字は120度、
さらに`rotate(PI / 3)`で左の文字は180度回転し、水平になっていることが分かります。



### Type
```typescript
rotate(angle: number, axis?: Vector | number[]): p5;
```
引数
- angle 回転させる角度
- axis 回転する軸をVetorで渡せる

第二引数で3Dにも対応しているようです。

### どんな時に使えそうか
回転を表現したいパターンはたくさん出てくると思います。
上記のコードに加算されていく変数を加えるだけで、表現の幅がぐっと広がるのが分かります。

毎フレーム0.05がプラスされる変数incを定義し、rotateの引数に渡す。

```javascript
function setup() {
  createCanvas(600, 600);	
  noStroke()
}

let inc = 0

function draw() {
  background(0)
  fill('white')
  translate(width / 2, height / 2)
  
  rotate(inc) // 3で割る
  rect(-100, -100, 200, 200)
  
  fill('red')
  textSize(32);
  text(PI / 3, 100, 100) // 引数の中身を表示
  
  inc = inc + 0.05
}
```

![画面収録-2021-12-16-12.06.22.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358229/9174a024-41b4-7f2c-14cf-c0cc90b8919f.gif)


また`background(0)`をsetup内に置いて残像を残すとこんな感じに

![rotate__残像あり.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358229/bb147d04-838f-60e2-99e3-ec6ee184fe2f.gif)


## 参考
[p5.js reference | rotate()](https://p5js.org/reference/#/p5/rotate)