递归变量问题——谢尔宾斯基地毯绘制
谢尔宾斯基地毯递归绘制问题排查与修复
嘿,我太懂这种递归图形卡壳的感觉了——谢尔宾斯基地毯的9分区域逻辑,最容易在坐标偏移和变量传递上掉坑。你说只有左上角能绘制,基本可以锁定是其他7个子区域的递归调用参数(坐标/宽高)没算对,大概率和你提到的变量混淆有关。
核心问题分析
谢尔宾斯基地毯的递归逻辑是:把当前正方形分成9个等大的小正方形,跳过中心那个,对剩下8个分别递归绘制。如果只出左上角,说明你要么没调用其他7个区域的递归,要么调用时的起始坐标/宽高用错了变量。
结合你给出的代码片段int smallerWidth = newWidth / 3; int smallerHeight =...,最可能的错误点有两个:
- 坐标偏移计算遗漏:其他子区域的起始x/y需要基于当前区域的坐标加上对应的偏移量(比如右上角是
当前x + 2*smallerWidth),如果所有递归都用了左上角的坐标,自然只有那里有图形。 - 变量层级混淆:如果
newWidth是全局变量或者上层递归的变量,而不是当前递归层传入的宽高,会导致后续子区域的宽高计算错误,进而影响坐标和绘制范围。
修复示例与检查要点
假设你的递归函数结构类似这样,我给你标出错漏的关键部分:
// 正确的递归函数示例(以Java为例,其他语言逻辑一致) void drawSierpinski(int currentX, int currentY, int currentWidth, int currentHeight) { // 终止条件:当图形小到一定程度停止递归 if (currentWidth < 4 || currentHeight < 4) { return; } // 用当前层的宽高计算小区域尺寸,别用全局/上层变量! int smallerWidth = currentWidth / 3; int smallerHeight = currentHeight / 3; // 绘制中心空白矩形(根据你的需求是填充或留白) fillRect(currentX + smallerWidth, currentY + smallerHeight, smallerWidth, smallerHeight); // 重点:必须递归调用8个周边子区域,每个的坐标偏移要准确 // 第一行三个 drawSierpinski(currentX, currentY, smallerWidth, smallerHeight); // 左上(你现在能画的就是这个) drawSierpinski(currentX + smallerWidth, currentY, smallerWidth, smallerHeight); // 中上 drawSierpinski(currentX + 2 * smallerWidth, currentY, smallerWidth, smallerHeight); // 右上 // 第二行左右两个(中心跳过) drawSierpinski(currentX, currentY + smallerHeight, smallerWidth, smallerHeight); // 左中 drawSierpinski(currentX + 2 * smallerWidth, currentY + smallerHeight, smallerWidth, smallerHeight); // 右中 // 第三行三个 drawSierpinski(currentX, currentY + 2 * smallerHeight, smallerWidth, smallerHeight); // 左下 drawSierpinski(currentX + smallerWidth, currentY + 2 * smallerHeight, smallerWidth, smallerHeight); // 中下 drawSierpinski(currentX + 2 * smallerWidth, currentY + 2 * smallerHeight, smallerWidth, smallerHeight); // 右下 }
你可以按这几个方向排查:
- 检查是否漏掉了上述示例中除左上以外的7次递归调用;
- 确认
smallerWidth/smallerHeight是用当前递归层传入的宽高计算的,而不是复用了上层的newWidth之类的变量; - 临时打印每次递归调用的
currentX、currentY、smallerWidth值,看看其他区域的参数是否明显异常(比如x/y始终是0,或者宽高不对)。
内容的提问来源于stack exchange,提问作者Eddoasso
相关产品推荐
相关产品推荐

