パドヴァン数列の螺旋を描画

こういうのを描きたい。

![padovan-spiral-0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127130/7a779ff6-eb42-cd10-3e14-be977bcb804d.png)

正三角形の辺の長さは、小さいほうから順に `1, 1, 1, 2, 2, 3, 4, 5, 7, 9, ...` となっている。

## パドヴァン数列
正三角形の辺の長さは以下の漸化式で表される。

```math
a_1 = a_2 = a_3 = 1 \\
a_{n} = a_{n-2} + a_{n-3} \; \left( n \gt 3 \right) \\
```

[A134816 : Padovan's spiral numbers - オンライン整数列大辞典](https://oeis.org/A134816)

有名なフィボナッチ数列や、それを元にしたトリボナッチ数列は、直前の2〜3項を全て足していた。パドヴァン数列では*直前の1項はスキップして*さらに前の2項を足す。（数列にゼロを含めていいのなら、初期値は 1, 0, 0 でいい：[A000931](https://oeis.org/A000931)）

<!--
なお数学的には、初期値を変えた[ペラン数列](https://ja.wikipedia.org/wiki/ペラン数)のほうが面白いのかもしれない。
-->

### 等比数列への漸近
フィボナッチ数列などと同様に、パドヴァン数列も数が大きくなると**直前の項との比が一定値に収束する**。

<!--
```ruby
$a = [nil, 1, 1, 1]
def a(n); $a[n] ||= a(n-2) + a(n-3); end
10.step(70, 10) { |n| puts "%4d%12d%12d%15.9f..." % [n, a(n), a(n-1), a(n).fdiv(a(n-1)).floor(9)] }
```
-->

```text
#  n        a[n]      a[n-1]     a[n] / a[n-1]
  10           9           7    1.285714285...
  20         151         114    1.324561403...
  30        2513        1897    1.324723247...
  40       41824       31572    1.324718104...
  50      696081      525456    1.324717959...
  60    11584946     8745217    1.324717957...
  70   192809420   145547525    1.324717957...
```

この定数は[**プラスチック数**](https://ja.wikipedia.org/wiki/プラスチック数)と呼ばれる。数列の特性方程式の解になっている。

```math
\begin{align}
\alpha^3 &= \alpha + 1 \\
\alpha^3 - \alpha - 1 &= 0 \\
\end{align}
```

### 別の漸化式
螺旋の絵からは、重なる辺に注目した次の式のほうが思いつきやすい。

```math
a_{n} = a_{n-1} + a_{n-5} \; \left( n \gt 5 \right)
```

これの特性方程式は因数分解できて、先ほどと同じ因子が登場する。（解にプラスチック数が出るはずのため当然ではある）

```math
\begin{align}
\alpha^5 &= \alpha^4 + 1 \\
\alpha^5 - \alpha^4 - 1 &= 0 \\
\left( \alpha^2 - \alpha + 1 \right) \left( \alpha^3 - \alpha - 1 \right) &= 0
\end{align}
```

## 頂点座標の列
正三角形かつ辺の長さが既知であることなどを利用して簡単に求める方法はありそうだが、**座標のとりかたに依存せずベクトルで考える**こともできる。

```math
\vec{r}_{n} = \vec{r}_{n-7} + \left( \vec{r}_{n-4} - \vec{r}_{n-3} \right) + \left( \vec{r}_{n-1} - \vec{r}_{n-2} \right)
```

三角形の頂点は $\left( \vec{r}\_{n-5}, \vec{r}\_{n-1}, \vec{r}\_{n} \right)$ で与えられる。

座標のとりかたはひとまず、2つの単位ベクトルの成す角が120°となるようにする（複素数平面で言えば、[アイゼンシュタイン整数](https://ja.wikipedia.org/wiki/アイゼンシュタイン整数) $a+b\omega$ ）。上の漸化式が使えるよう7点の座標を手入力し、さらに三角形の頂点のために $-4 \le n \lt 1$ まで外挿すると、以下のようになる。

```text
#  n  x[n]  y[n]
  -4     0     0
  -3     0     0
  -2     0     0
  -1     1     0
   0     1     0
   1     1     1
   2     0     1
   3    -1     0
   4    -1    -2
   5     1    -2
   6     4     1
   7     4     5
   8    -1     5
   9    -8    -2
  10    -8   -11
  11     4   -11
  12    20     5
```

### 変換行列を用いて描画
ベクター画像を扱うものなら変換行列を指定できる場合が多い。これによって、上記の座標値をそのまま入力しておいて座標変換は描画処理に任せることもできる。

※ただ、線の太さまで座標変換の影響を受ける場合、線の方向によって太さが変わって見栄えが悪くなってしまう。

```xml:padovan-spiral.svg
<svg width="1340" height="780" viewBox="-400 -240 1340 780" version="1.1"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
	<g fill="none" stroke="black" stroke-width="0.1" stroke-linejoin="bevel"
	   transform="scale(10 -10) matrix(1 0 -0.5 0.8660254 0 0)">
		<polygon points="0,0 1,0 1,1" />
		<polygon points="0,0 1,1 0,1" />
		<polygon points="0,0 0,1 -1,0" />
		<polygon points="1,0 -1,0 -1,-2" />
		<polygon points="1,0 -1,-2 1,-2" />
		<polygon points="1,1 1,-2 4,1" />
		<polygon points="0,1 4,1 4,5" />
		<polygon points="-1,0 4,5 -1,5" />
		<polygon points="-1,-2 -1,5 -8,-2" />
		<polygon points="1,-2 -8,-2 -8,-11" />
		<polygon points="4,1 -8,-11 4,-11" />
		<polygon points="4,5 4,-11 20,5" />
		<polygon points="-1,5 20,5 20,26" />
		<polygon points="-8,-2 20,26 -8,26" />
		<polygon points="-8,-11 -8,26 -45,-11" />
		<polygon points="4,-11 -45,-11 -45,-60" />
		<polygon points="20,5 -45,-60 20,-60" />
		<polygon points="20,26 20,-60 106,26" />
	</g>
</svg>
```

SVGのtransform属性：https://developer.mozilla.org/ja/docs/Web/SVG/Attribute/transform