クロソイド曲線（オイラー曲線）

# はじめに
AppleのMacBookやiPhoneや、アイコンの角にクロソイド曲線が使われているという記事を見つけたので、自分なりに検証してみた話です。

https://gigazine.net/news/20170127-apple-icon-shape/

https://crft.jetsets.jp/adobe-illustrator/clothoid-rounded-corner-square/

https://www.gearrice.com/update/the-beauty-of-apple-products-goes-beyond-technology-it-is-also-geometry/

結論からいうと、
「Appleのアイコンのテンプレは、クロソイド曲線には一致しない」
また、
「スーパー楕円にも一致しないが、クロソイド曲線より近似する」
そして、
「拡張バラ曲線にも一致しないが、上の２曲線より近似する」
というところまで、わかりました。

・・・まだ、ピッタリとあう曲線は見つかっていません。
Apple配布のデータも、ベクターデータではなく、画像データなので、いまいち、精度に不安が残ります。

※「曲率が連続的に変化する」ということは、ほぼ言えますが、説明できる数式が見当たらない状況です。


# 曲率とは

曲率とは、曲線の曲がり具合を示し、円は曲率が一定の曲線である。
例えば、角丸四角は直線と円弧（四分円）で構成されていて、直線と円弧の接続部では、曲率は不連続である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/18a0b5f6-5b75-5a00-7922-b3df958d8ae8.png)

# クロソイド曲線とは
円弧に対して、クロソイド曲線は曲率が徐々に変化する（変化率が一定な）曲線である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/258f52d1-0241-03e1-7d72-a3383abfd9f5.png)

そのため、
高速道路のカーブ、
ジェットコースターのループ、
に使われている、そうだ。

# Appleサイトからアイコンのテンプレを入手
https://developer.apple.com/design/resources/
Photoshop形式
January 19, 2023
3.1 MB
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/c70c2035-4aaf-fe0c-4695-43c7a1ca30a1.png)

# wikiからクロソイド曲線のSVGファイルを入手
https://upload.wikimedia.org/wikipedia/commons/9/91/Euler_spiral.svg

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/257a012a-5cf1-9eb9-06f5-cf0c29012660.png)

重ね合わせてみますが、一致しませんでした。
あれ？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/b3e805b1-315b-a0ec-a814-39504c859a77.png)

# スーパー楕円でどうだ
指数が3のスーパー楕円が一番近いが、一致はしない。
クロソイドよりも若干だが近い。

黄：2(円弧・角丸四角）
黒：3
緑：4

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/47cae9a2-664c-984f-03e4-0b4dfa470688.png)

# 拡張バラ曲線でどうだ
バラ曲線の一般式
```math
r=Asin(n\theta)
```
その変形式
```math
r=Asin(n\theta)+(1-A)
```
※こちらのサイトの式を参考にしました。

https://note.com/sciencecafe_mc2/n/nbab7361ad113

どっかで見た気がするけど、思い出せない。

青（A=0.053：b=4）
紫（A=0.055：b=4）

紫の線が一番近い。
（スーパー楕円より近い）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/f806bc30-f0b0-10c4-2d99-8fbed2d85b3e.png)

ピッタリの式が見つからない。
謎は深まる。
単なるベジェなのかな…


# クロソイドの作図
定義より
```math
x(L)=\int_0^L cos(\theta^2)d\theta
```
```math
y(L)=\int_0^L sin(\theta^2)d\theta
```

### シンプソン法

```math
\frac{h}{3}(f_0+4f_1+f_2)
```
```math
\int_a^b f(x)dx\approx\frac{b-a}{6}\lbrack f(a)+4f(\frac{a+b}{2})+f(b)\rbrack
```

上記の式より

```math
x(L)\approx\frac{h}{6}(cos\theta_0^2+4cos(\frac{\theta_0+\theta_1}{2})^2+cos\theta_1^2)
```
```math
y(L)\approx\frac{h}{6}(sin\theta_0^2+4sin(\frac{\theta_0+\theta_1}{2})^2+sin\theta_1^2)
```
と近似できるので、刻み値hを小さく取り、累積していく。



## エクセルで計算
エクセル計算においては下記サイトを参考にした。

https://sci.tea-nifty.com/blog/2010/11/excel-4799.html

　エクセルの散布図グラフでX座標とY座標をプロットし、縦軸と横軸は0~1の範囲に固定したのち、グラフをコピー＆ペーストでイラレに持っていく。
　ただし、エクセルでグラフの縦横比を1:1にしなくてはならないのだが、エクセルのUIの仕様により、厳密に揃えることができないので、注意（許容）しなければならない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/bc792c37-03e8-2565-651f-c0c0b31bd0c7.png)

## processingで計算
　エクセルでグラフ書くのは楽だが、グラフの縦横比を正確に1:1にできないので、ProcessingでPDF書き出しする。

```java
import processing.pdf.*;

size(500, 500);

beginRecord(PDF, "clothoid0001.pdf");

translate(250, 250);
noFill();

float x=0, y=0;

beginShape();
vertex(0, 0);

float dt = 0.001;
for (float t=0; t<8; t+=dt) {
  float u = t+dt;
  x += dt*(cos(t*t)+cos(u*u)+4*cos((t+u)*(t+u)/4f))/6f;
  y += dt*(sin(t*t)+sin(u*u)+4*sin((t+u)*(t+u)/4f))/6f;
  vertex(x*200, -y*200);
}
endShape();

endRecord();
```
刻み値dtを変化させて、プログラムの信頼度を観察。
0.1(赤)
0.01(緑)
0.001(青)
0.0001(黃)
0.00001(水)
wikiのsvgデータ(黒)※正確とおもわれる

目視では、dt=0.001あれば十分な精度が得られる。
0.0001や0.00001になると、Processing上での表示と、PDF書き出しは成功するが、イラレで開いたときに、表示が欠ける問題が生じた。おそらく、１パス内の頂点数の限界があるのだろう。

![Processingクロソイドdt精度比較.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/48cd2314-474a-0be3-4c56-167a4d8e84ad.png)


# スーパー楕円の作図

ついでにスーパー楕円のプログラムも載せておく。

```java
import processing.pdf.*;

size(500, 500);

beginRecord(PDF, "superEllipse.pdf");

translate(250, 250);
noFill();

float x=0, y=0;

beginShape();

float dt = 0.001;
float n = 3;
for (float th=0; th<2*PI; th+=dt) {
  x = pow(abs(cos(th)),2f/n) * (0<cos(th) ? 1 : -1);
  y = pow(abs(sin(th)),2f/n) * (0<sin(th) ? 1 : -1);
  vertex(x*200, -y*200);
}
endShape(CLOSE);

endRecord();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/3a04d76c-b404-c808-555b-68d6a9a32bab.png)


# 参考サイト

日本語wikiのクロソイドと、英語wikiのEuler_spiralでは、式がやや違うため、全体的に√2倍？サイズが違う。なんでだろう？

https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%BD%E3%82%A4%E3%83%89%E6%9B%B2%E7%B7%9A

https://en.m.wikipedia.org/wiki/Euler_spiral

https://commons.wikimedia.org/wiki/Category:Euler_spirals#/media/File:Clothoide.svg

https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%B3%E3%83%97%E3%82%BD%E3%83%B3%E3%81%AE%E5%85%AC%E5%BC%8F

https://shintani.fpark.tmu.ac.jp/classes/information_processing_2/integration_2/simpson.html



Overgangsboog（遷移円弧）

https://nl.wikipedia.org/wiki/Overgangsboog

https://crft.jetsets.jp/adobe-illustrator/clothoid-rounded-corner-square/

https://sci.tea-nifty.com/blog/2010/11/excel-4799.html