1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Flutter】ポリゴン多角星の描画(CustomPaint応用編)

Last updated at Posted at 2023-02-11

※本記事は下記の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);

countを10にすると下記のような10角星できました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?