3D vector邻域填充优化:如何兼容网格边界的球形源设置需求
3D网格球形源填充优化方案
原有代码问题分析
- 未先校验中心坐标
(x,y,z)的合法性,直接访问vec[z][y][x]会在中心本身越界时触发内存访问错误 - 外层if判断要求
x/y/z都必须同时大于0且小于对应维度的最大索引,只要中心处于任意边界(如x=0、z = vec.size()-1等场景),所有邻域填充逻辑都会直接跳过,导致边界场景失效 - 硬编码26个邻域的写入逻辑,代码冗余且易出错
优化实现思路
通过三层循环遍历dx/dy/dz从-1到1的所有组合,自动覆盖中心+26个邻域的所有场景,每一步先校验目标坐标合法性,再根据偏移量自动计算对应权重,无需手动编写分支处理边界场景。
权重计算规则和原有逻辑完全对齐:
- 偏移非零维度数为0(中心):权重 = maxAct / 1
- 偏移非零维度数为1(面相邻):权重 = maxAct / 2
- 偏移非零维度数为2(边相邻):权重 = maxAct / 3
- 偏移非零维度数为3(顶点相邻):权重 = maxAct / 4
优化后代码
void setSphericalSource(int x, int y, int z, float sigma, vector<vector<vector<float>>>& vec, float maxAct) { // 先获取各维度最大长度,避免重复计算 int z_size = vec.size(); if (z_size == 0) return; int y_size = vec[0].size(); if (y_size == 0) return; int x_size = vec[0][0].size(); if (x_size == 0) return; float total_activity = 0.0; // 遍历x/y/z三个方向的所有±1偏移组合 for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { for (int dz = -1; dz <= 1; dz++) { // 计算目标坐标 int nx = x + dx; int ny = y + dy; int nz = z + dz; // 校验坐标合法性,越界直接跳过 if (nx < 0 || nx >= x_size || ny < 0 || ny >= y_size || nz < 0 || nz >= z_size) { continue; } // 计算非零偏移的维度数 int offset_cnt = abs(dx) + abs(dy) + abs(dz); // 计算权重并赋值 float val = maxAct / (offset_cnt + 1); vec[nz][ny][nx] = val; total_activity += val; } } } // 原有逻辑的total_activity变量可根据需求后续处理 }
方案优势
- 自动适配所有中心位置场景:中心在网格内部、面、边、顶点时都能正常写入合法邻域,自动跳过越界坐标
- 代码量大幅缩减,无冗余硬编码逻辑,可读性和可维护性更高
- 权重计算逻辑可灵活调整,后续如果需要修改不同邻域的权重规则,只需修改
val的计算行即可
内容的提问来源于stack exchange,提问作者Ferrarista
相关产品推荐
相关产品推荐

