背景
2022卡塔尔世界杯是足球爱好者的狂欢,这与我毫无关系,作为一个缺乏运动的人,还是不要去看人家玩命的运动了。虽然不看球,不过这波热度的持续冲击,还是让我在朋友圈刷到了结局 ———— 球王梅西如愿以偿捧得金杯,后起之秀姆巴佩加冕金靴。但作为程序员,为了增加一些参与感我就拿 C# 画个足球图案吧。
Graphics 介绍
图案的绘制方法非常简单,使用 C# 的 System.Drawing 命名空间中的 Graphics 类的方法即可在窗体、控件、图像或其他绘图表面上绘制文本、线条、图像和其他图形。
下面是一些常见的 Graphics 类方法:
- DrawLine: 绘制一条从一个点到另一个点的直线。
- DrawRectangle: 绘制一个矩形。
- DrawEllipse: 绘制一个椭圆。
- DrawString: 绘制文本。
- FillRectangle: 填充一个矩形。
- FillEllipse: 填充一个椭圆。
- Clear: 清除图形表面上的所有图形。
要使用 Graphics 类,需要创建一个 Graphics 对象,并使用其绘图方法绘制图形。例如,要在窗体上绘制一条直线,可以使用以下代码:
using System.Drawing;
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.DrawLine(Pens.Black, 0, 0, 100, 100);
}
还可以使用 Graphics 类的 DrawImage 方法绘制图像,使用 DrawCurve 方法绘制曲线,使用 DrawPolygon 方法绘制多边形,等等。
足球绘制
使用 DrawPolygon 方法绘制多边形,我们可以简单的绘制一个足球图案。绘制足球就要绘制五边形,或者六边形。可以使用 Math.Cos
和 Math.Sin
函数来计算五边形的顶点坐标,比如已知五边形的中心坐标点 Point(centerX,centerY)
和边长 sideLength
后,我们可以通过下面的公式计算获取五个顶点的坐标:
Point point1 = new Point(centerX + (int)(sideLength * Math.Cos(Math.PI / 5)), centerY - (int)(sideLength * Math.Sin(Math.PI / 5)));
Point point2 = new Point(centerX + (int)(sideLength * Math.Cos(3 * Math.PI / 5)), centerY - (int)(sideLength * Math.Sin(3 * Math.PI / 5)));
Point point3 = new Point(centerX + (int)(sideLength * Math.Cos(5 * Math.PI / 5)), centerY - (int)(sideLength * Math.Sin(5 * Math.PI / 5)));
Point point4 = new Point(centerX + (int)(sideLength * Math.Cos(7 * Math.PI / 5)), centerY - (int)(sideLength * Math.Sin(7 * Math.PI / 5)));
Point point5 = new Point(centerX + (int)(sideLength * Math.Cos(9 * Math.PI / 5)), centerY - (int)(sideLength * Math.Sin(9 * Math.PI / 5)));
然后将其连接起来绘制多边形进行填充颜色即可:
// 创建五边形路径
Point[] points = { point1, point2, point3, point4, point5 };
g.DrawPolygon(Pens.Black, points);
g.FillPolygon(new SolidBrush(Color.Black), points);
但是绘制了中间的五边形后,就需要根据五边形继续计算五个六边形的坐标,这样就非常麻烦了,经过几番尝试后,我找到了一种比较简单的绘制足球的方法:首先绘制一个六边形,然后选择一个外部的圆心对这个六边形坐标进行旋转 72 度,这样旋转几次,我们就画好了五个六边形,填充白色。然后在画五边形的代码前面加画一个填充黑色的大圆,足球就这样画好了:
// 获取绘图对象
Graphics g = this.CreateGraphics();
int width = 100; // 六边形的宽度
int height = 100; // 六边形的高度
int x = 100; // 六边形的横坐标
int y = 200; // 六边形的纵坐标
Point center = new Point(x + width + width, y + height / 2);
// 最外围大圆直径
int d = 4 * width + width / 2;
Rectangle rect = new Rectangle(center.X - d / 2, center.Y - d / 2, d, d);
g.FillEllipse(new SolidBrush(Color.Black), rect);
g.DrawEllipse(new Pen(Color.Black), rect);
Point[] points = {
new Point(x, y),
new Point(x + width / 2, y - height / 2),
new Point(x + width, y),
new Point(x + width, y + height),
new Point(x + width / 2, y + height + height / 2),
new Point(x, y + height)
};
// 创建一个矩阵
Matrix transform = new Matrix();
// 旋转绘制六边形
for (int i = 0; i < 5; i++)
{
// 绘制
g.DrawPolygon(Pens.Black, points);
g.FillPolygon(new SolidBrush(Color.White), points);
// 以 center 为中心进行 72 度的旋转
transform.RotateAt(72, center);
// 应用旋转,下次绘制
g.Transform = transform;
}
绘制效果
最后代码运行的绘制效果如下:
项目代码开源在 gitcode,仓库地址:https://gitcode.net/marin1993/football