用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或宽度不同于高度时保持其形状

例如,如果我将大小设置为50×50,则会发生这种情况:

在此处输入图像描述

我会给你一个不同的方法。 将八边形视为八边形的圆形圆圈。

Octogon重叠在一个圆圈上

从圆的原点,您可以使用三角学计算角度t (以弧度表示)和半径r的沿着角落边缘的点。

 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(); 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); 

如果您不希望它变形,只需使用最小边的半径而不是用ab替换r

变形的octogon