※本記事は下記のZenn本にまとめました。
正多角形
点を収集できれば、いくら角あっても描けます。
下記のように三角形の頂点を収集すれば、addPolygonで三角形を描くことができます。
ブルー枠線は正三角形の外接円であり、正三角形の場合、その3点は外接円の0°、120°、240°です。三角関数の正弦、余弦でその点の座標を算出します。
for (int i = 0; i < count; i++) {
// 0°、120°、240°
double perRad = 2 * pi / count * i;
points.add(Offset(radius * cos(perRad), radius * sin(perRad)));
}
点の集合取得できれば、path.addPolygon関数で正三角形を描画できます。
Path path = Path();
Paint paint = Paint()
..color = Colors.red
..strokeWidth = 2
..style = PaintingStyle.stroke;
int count = 3;
double radius = 100;
List<Offset> points = [];
for (int i = 0; i < count; i++) {
// 始点は0°
double perRad = 2 * pi / count * i;
points.add(Offset(radius * cos(perRad), radius * sin(perRad)));
}
path.addPolygon(points, true);
canvas.drawPath(path, paint);
では、同じ方法で上記count値で外接円を均等で分けて、その点を収集できれば、正多角形の描画もできます。
正四角形 | 正五角形 | 正六角形 | 正十角形 |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
※上記例は始点0°となっています。もし多角形の向きを調整したい場合、その始点を調整すれば、簡単にできます。
// 偏移値
double offset = -pi / 2;
points.add(
Offset(
radius * cos(perRad + offset),
radius * sin(perRad + offset),
),
);
star
上記の方法で多角形描けましたので、同じ方法で二つの多角形を描いて、点と点を連結すれば、星になるでしょう。
int count = 5;
double outRadius = 100;
double innerRadius = 50;
List<Offset> points = [];
for (int i = 0; i < count; i++) {
double perRad = 2 * pi / count * i;
points.add(Offset(outRadius * cos(perRad), outRadius * sin(perRad - pi / 2)));
points.add(Offset(innerRadius * cos(perRad), innerRadius * sin(perRad - pi / 2)));
}
path.addPolygon(points, true);
では、その内部の円を右へちょっと偏移すれば、綺麗になります。
for (int i = 0; i < count; i++) {
double perRad = 2 * pi / count * i;
points.add(Offset(outRadius * cos(perRad - pi / 2), outRadius * sin(perRad - pi / 2)));
points.add(
Offset(
innerRadius * cos(perRad - pi / 2 + offset),
innerRadius * sin(perRad - pi / 2 + offset),
),
);
}
path.addPolygon(points, true);
n角星
五角星描けましたので、その偏移値 β と n の関係分かれば、n角星も描けると思います。
n 角形の内角の和の式は, 180°×n -360°
下記 α は正五角形内角の1つですから、α=(180°×5 -360°)/5=108°。
従って、β=180°-108°/2-90°=36°。
β=180°-(180°*n -360°)/n/2-90°
β=180°/n
偏移値は pi / countとなります。
int count = 5;
double outRadius = 100;
double innerRadius = 50;
double offset = pi / count;
List<Offset> points = [];
for (int i = 0; i < count; i++) {
// 始点は0°
double perRad = 2 * pi / count * i;
points.add(Offset(outRadius * cos(perRad - pi / 2), outRadius * sin(perRad - pi / 2)));
points.add(
Offset(
innerRadius * cos(perRad - pi / 2 + offset),
innerRadius * sin(perRad - pi / 2 + offset),
),
);
}
path.addPolygon(points, true);