在 C# 中填充八边形

Fill Octagon in C#

我创建了一个绘制八边形的方法,效果很好,只要大小为200或更高

public static void FillOctagon(PaintEventArgs e, Color color, int x, int y, int width, int height)
{
     e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

     var points = new []
     {
          new Point(((x + width) / 2) - (width / 4), y), //side 1
          new Point(x, ((y + height) / 2) - (height / 4)), //side 2
          new Point(x, ((y + height) / 2) + (height / 4)), //side 3
          new Point(((x + width) / 2) - (width / 4), y + height), //side 4
          new Point((x + width) - (width / 4), y + height), //side 5
          new Point(x + width, ((y + height) / 2) + (height / 4)), //side 6
          new Point(x + width, ((y + height) / 2) - (height / 4)), //side 7
          new Point((x + width) - (width / 4), y) //side 8
     };

     using (var br = new SolidBrush(color))
     {
          using (var gpath = new GraphicsPath())
          {
              gpath.AddPolygon(points);
              e.Graphics.FillPath(br, gpath);
          }
     }
}

protected override void OnPaint(PaintEventArgs e)
{
     base.OnPaint(e);
     FillOctagon(e, Color.DodgerBlue, 20, 20, 50, 50);
}

嗯,我的问题是,如果尺寸小于 200 或者宽度与高度不同,反之亦然,图形就会变形。 我的目标是创建一个自适应图形,当宽度和高度小于 200 或者宽度与高度不同时保持其形状

This is what happens if, for example, I set the size to 50x50:

我给你一个不同的方法。将八角形想象成一个 eight-sided 块状圆圈。

从圆的原点,给定角度 t(以弧度为单位)和半径 r[,您可以计算沿圆周边缘的点=39=] 使用三角函数。

x = r cos t
y = r sin t

您可以应用此方法计算八边形(或任意边数的等边形)的点,但它无法变形(拉伸)。为了使其变形,公式略有变化(其中a为水平半径,b为垂直半径)

x = a cos t
y = b sin t

这可能是代码中的样子 - 我已经修改了您在本例中的代码。

public static void FillEquilateralPolygon(PaintEventArgs e, int sides, Color color, double x, double y, double width, double height)
{
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    double a = width / 2;
    double b = height / 2;

    var points = new List<Point>();

    for (int pn = 0; pn < sides; pn++)
    {
        double angle = (360.0 / sides * pn) * Math.PI / 180;
        double px = a * Math.Cos(angle);
        double py = b * Math.Sin(angle);
        var point = new Point((int) (px + x), (int) (py + y));
        points.Add(point);
    }

    using (var br = new SolidBrush(color))
    {
        using (var gpath = new GraphicsPath())
        {
            gpath.AddPolygon(points.ToArray());
            e.Graphics.FillPath(br, gpath);
        }
    }
}

现在可以调用这个方法,传入8个边,渲染一个可以变形的八边形

FillEquilateralPolygon(e, 8, Color.Red, 201, 101, 201, 101);

如果你不想让它变形,就用最小边的半径代替 rab.