C++实现2D矩阵指定点周围圆形高度填充问题排查
问题分析与修复方案
核心错误点
- 距离计算逻辑错误:误用外层循环的峰值索引参与距离计算,应当使用当前遍历点相对于峰值中心的偏移量
- 矩阵索引计算错误:索引公式完全不符合一维矩阵的寻址规则,且未做边界检查,导致无效写入或越界
- 未实现“随靠近中心值递增”的需求:当前直接写入固定范围随机数,未关联距离与数值的递增关系
修复细节
1. 修正距离计算
原代码错误地使用峰值循环索引i计算距离,应替换为当前遍历点相对于中心的偏移量:
// 计算当前点相对于峰值中心的坐标差 int dx = k - radius; int dy = j - radius; // 如需精确距离可保留sqrt,仅判断是否在圆内可直接用平方比较(避免浮点运算) double distance = sqrt(dx * dx + dy * dy);
2. 修正矩阵索引与边界检查
原索引公式完全错误,需先计算绝对坐标,再转成一维矩阵索引,同时必须检查边界避免越界:
// 计算当前点的绝对坐标 int currX = x + dx; int currY = y + dy; // 检查是否在矩阵范围内 if (currX >= 0 && currX < 50 && currY >= 0 && currY < 50) { // 一维矩阵标准寻址:行号 * 列数 + 列号 int matrixIndex = currX * columns + currY; // 后续赋值逻辑 }
3. 实现“随距离递增”的数值生成
通过距离比例线性插值,让数值从边缘低值到中心峰值逐步递增:
// 跳过圆外的点 if (distance > radius) continue; // 归一化距离比例(0为中心,1为边缘) double ratio = distance / radius; // 生成从边缘到中心递增的随机数,边缘取值10-20,中心接近峰值高度 int minVal = 10; int currentMax = minVal + (int)((peakHeight - minVal) * (1 - ratio)); // 确保最大值不小于最小值 currentMax = std::max(currentMax, minVal); matrix[matrixIndex] = randomize(minVal, currentMax);
修复后的完整circleGen函数
void circleGen(std::vector<int> peaks, int columns) { for (int peakIdx = 0; peakIdx < peaks.size(); peakIdx++) { int radius = randomize(5, 15); int index = peaks[peakIdx]; int x = index / 50; int y = index % 50; int peakHeight = matrix[index]; // 遍历以峰值为中心的正方形区域 for (int k = 0; k < radius * 2; k++) { for (int j = 0; j < radius * 2; j++) { int dx = k - radius; int dy = j - radius; double distance = sqrt(dx * dx + dy * dy); // 仅处理圆形范围内的有效点 if (distance > radius) continue; int currX = x + dx; int currY = y + dy; if (currX < 0 || currX >= 50 || currY < 0 || currY >= 50) continue; // 计算矩阵索引并赋值 int matrixIndex = currX * columns + currY; int minVal = 10; double ratio = distance / radius; int currentMax = minVal + (int)((peakHeight - minVal) * (1 - ratio)); currentMax = std::max(currentMax, minVal); matrix[matrixIndex] = randomize(minVal, currentMax); } } } }
额外优化建议
- 移除硬编码的
50:将矩阵行列数作为参数传入,提升代码灵活性 - 峰值去重:
sprinklePeaks函数可能生成重复索引,可加入去重逻辑避免峰值覆盖 - 随机数优化:建议使用C++标准库
<random>替代自定义randomize,避免序列重复问题
内容的提问来源于stack exchange,提问作者hrodric
相关产品推荐
相关产品推荐

