如何将均匀分布的点数组排序为正方形分组?C#实现求助
解决均匀分布点分组排序以形成正方形区域的问题
看起来你想把网格里的均匀分布点划分成连续的组,每组的点都落在一个正方形区域里对吧?我看你生成了6×6的网格点集合(共36个点),设置的n=9,刚好是要分成4个3×3的正方形块,每组9个点。咱们一步步来解决这个问题:
核心思路
- 确定块尺寸:总点数是
width * height = 36,每组n=9个点,所以一共分成36/9=4组,对应2×2的块矩阵。每个块的边长是width / 2 = 3(因为你的宽高相等,若宽高不等可以调整计算逻辑)。 - 给点分配组编号:根据点的x、y坐标,判断它属于哪个正方形块,用统一编号把同一块的点归为一组。
- 排序分组:先按组编号排序,保证同一正方形块的点连续排列;组内可以按坐标排序,让点的顺序更整洁。
完整实现代码
class Point { public int x; public int y; // 方便打印调试,可选 public override string ToString() => $"({x}, {y})"; } class Program { static void Main(string[] args) { var points = new List<Point>(); int width = 6; int height = 6; int n = 9; // 生成均匀分布的网格点 for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { points.Add(new Point() { x = x, y = y }); } } // 计算块的数量和每个块的边长 int totalGroups = (width * height) / n; int blocksPerSide = (int)Math.Sqrt(totalGroups); // 2×2的块矩阵 int blockSize = width / blocksPerSide; // 每个块的边长为3 // 排序:先按组编号聚合同块的点,再按x、y坐标整理组内顺序 var sortedPoints = points.OrderBy(p => GetGroupNumber(p, blockSize, blocksPerSide)) .ThenBy(p => p.x) .ThenBy(p => p.y) .ToList(); // 打印验证:每9个点一组,输出每组的点 for (int i = 0; i < sortedPoints.Count; i += n) { Console.WriteLine($"第{(i/n)+1}组(共{n}个点):"); for (int j = 0; j < n; j++) { Console.Write(sortedPoints[i+j] + " "); if ((j+1) % blockSize == 0) Console.WriteLine(); // 每行3个点,对齐网格 } Console.WriteLine("---"); } } // 计算点所属的组编号 static int GetGroupNumber(Point p, int blockSize, int blocksPerSide) { // 计算点所在块的x、y索引 int blockX = p.x / blockSize; int blockY = p.y / blockSize; // 把2D块索引转换成1D组编号:比如(0,0)→0,(1,0)→1,(0,1)→2,(1,1)→3 return blockY * blocksPerSide + blockX; } }
代码解释
GetGroupNumber方法:通过点的坐标除以块边长,得到点在2D块矩阵中的位置,再转换成一维组编号,确保同一块的点拥有相同编号,这样排序时就能自动聚合。- 排序逻辑:先用
OrderBy按组编号排序,保证同一正方形块的点连续;再用ThenBy按x、y排序,让组内的点按网格顺序排列,方便查看验证。 - 验证输出:代码里加入了打印逻辑,每9个点输出一组,你能清晰看到每组的点都落在3×3的正方形区域内(比如第一组是(0,0)到(2,2)的所有点)。
扩展说明
如果你的宽高不相等,或者n不是完全平方数的倍数,只需要调整blockSize和blocksPerSide的计算逻辑,核心的分组排序思路是通用的——只要先把点按所属正方形区域分组,再按组排序即可。
内容的提问来源于stack exchange,提问作者DrevanTonder
相关产品推荐
相关产品推荐

