如何用C# System.Drawing.Graphics绘制Google Pay样式点阵圆环
实现方案
核心调整逻辑
- 首先抽离所有可配置参数,和1/4圆环点位数直接关联:
QuarterSegmentBaseDotCount:每1/4圆环的基准点数,默认取12(整圈基准48点)DotDiameter:单个点的直径DotGap:相邻层点之间的预留间隙LevelCount:圆环层数,默认7(匹配Google Pay Spot码规格)CenterX/CenterY:绘制圆心坐标InnerRadius:最内层圆环的半径
- 对角交错排布实现:奇数层的起始角度偏移
dtheta/2(dtheta为当前层相邻点的角度间隔),即可实现相邻层点位交错的效果 - 点位数计算公式:每层整圈点位数 =
4 * (QuarterSegmentBaseDotCount + levelIndex),每向外一层,每1/4段增加1个点,完全匹配段点位关联需求 - 半径计算公式:每层半径 =
InnerRadius + levelIndex * (DotDiameter + DotGap),保证各层点不会重叠
修改后可配置的实现代码
// 可配置参数类,可根据需求调整 public class SpotCodeConfig { public int QuarterSegmentBaseDotCount { get; set; } = 12; public float DotDiameter { get; set; } = 8f; public float DotGap { get; set; } = 2f; public int LevelCount { get; set; } = 7; public float CenterX { get; set; } = 300f; public float CenterY { get; set; } = 300f; public float InnerRadius { get; set; } = 80f; public Brush[] ColorPalette { get; set; } = new Brush[] { Brushes.LightGoldenrodYellow, Brushes.DeepSkyBlue, Brushes.ForestGreen, Brushes.Red }; public Brush DefaultGrayBrush { get; set; } = Brushes.LightGray; } private void DrawSpot(Graphics graphics, SpotCodeConfig config) { // 开启抗锯齿提升绘制效果 graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; Random randomColor = new Random(); Random randomBit = new Random(); for (int level = 0; level < config.LevelCount; level++) { // 计算当前层整圈点位数:和每1/4段点位关联 int totalDotCount = 4 * (config.QuarterSegmentBaseDotCount + level); // 计算当前层角度间隔 float dtheta = (float)(2 * Math.PI / totalDotCount); // 计算当前层半径 float currentRadius = config.InnerRadius + level * (config.DotDiameter + config.DotGap); // 奇数层偏移半个角度间隔,实现交错排布 float startTheta = level % 2 == 0 ? 0f : dtheta / 2; for (int dotIndex = 0; dotIndex < totalDotCount; dotIndex++) { float theta = startTheta + dotIndex * dtheta; // 计算点的左上角坐标 float x = config.CenterX + (float)(currentRadius * Math.Cos(theta)) - config.DotDiameter / 2; float y = config.CenterY + (float)(currentRadius * Math.Sin(theta)) - config.DotDiameter / 2; // 选择点颜色,可根据业务需求修改规则 Brush brush; if (level == 0) { brush = dotIndex % 2 == 0 ? config.ColorPalette[randomColor.Next(config.ColorPalette.Length)] : config.DefaultGrayBrush; } else { brush = randomBit.Next(2) == 0 ? config.DefaultGrayBrush : config.ColorPalette[randomColor.Next(config.ColorPalette.Length)]; } // 填充圆点,替换原有的描边绘制 graphics.FillEllipse(brush, x, y, config.DotDiameter, config.DotDiameter); } } }
关键优化说明
- 替换原有的
DrawEllipse为FillEllipse,符合Spot码实心点的视觉效果 - 圆心坐标固定,避免原代码中圆心随层数偏移的问题
- 所有可调整参数统一封装到
SpotCodeConfig类中,调整规格不需要修改绘制逻辑 - 点位数计算和1/4段点位直接绑定,调整
QuarterSegmentBaseDotCount即可修改每段的基础点数量
内容的提问来源于stack exchange,提问作者Henka Programmer
相关产品推荐
相关产品推荐

