円をarc()で描画するのでなくbezierCurveTo()で描画すれば、湾曲させたり変形させたりできる。
bezierCurveTo()の詳細は調べればわかるので省く。
r = 10 // 任意の半径
kappa = 0.5522848;
o = r * kappa;
このo
が各制御点を計算するための基礎の値になるらしい。
kappa
が何故その値なのかは完全に理解していない。理屈については参考URLを参照のこと。
円周上の各点とその制御点の計算は以下。
p1.x = x - r * Math.cos(getRadian(deg));
p1.y = y - r * Math.sin(getRadian(deg));
p1.c1x = p1.x + o * Math.cos(getRadian(deg - 90));
p1.c1y = p1.y + o * Math.sin(getRadian(deg - 90));
p1.c2x = p1.x + o * Math.cos(getRadian(deg + 90));
p1.c2y = p1.y + o * Math.sin(getRadian(deg + 90));
ここで計算した点、制御点をbezierCurveTo()で繋げば円が描ける。
※getRadian() はradianをdegreeに変換する関数のつもり。