You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

填充圆绘制算法生成重复坐标点问题排查咨询

问题根源

重复点完全是逻辑设计问题,来源有两个:

  1. 同一水平扫描线被反复添加:中点圆迭代时x逐轮递增,但y只有决策变量d达到阈值才会递减,同一个y值会对应多轮x迭代。你每轮迭代都给当前y绘制从-x到x的水平线段,后一轮更长的线段会完全覆盖前一轮的短线段,被覆盖的点全部重复,示意图上下两端的!就是这么来的——比如半径5时y=5的线段,x=0时加了1个点,x=1时加了3个点,x=2时加了5个点,中间的点被重复加了2-3次。
  2. 特殊位置点重叠:当迭代到x=y的对角线位置时,水平线段和垂直线段的端点完全重合,会重复添加四个对角线点;x=0或y=0的坐标轴位置,对称判断逻辑也会重复加点。
排查思路

按这几步查,很快能定位:

  • 拿小半径(比如radius=2)单步调试,逐轮打印x、y值和当轮新增的点,对比已有点列表,一眼就能看到同一y值的线段被反复追加。
  • 把返回的points转成set去重后算长度,和填充圆理论点数对比,差值就是重复点数量,可以快速验证修复有没有效果。
  • 分别注释掉水平线段、垂直线段的绘制逻辑,单独看每部分输出的图形,就能定位哪段逻辑产生了重叠。
修复方案

方案1:最小改动快速修复

如果不想大改原有逻辑,直接在返回前对坐标去重即可,适合对性能要求不高的场景:

def get_filled_circle(radius):
    d = (5 - radius * 4) / 4.0
    x = 0
    y = radius

    points = []

    while True:
        for idx in range(-x, x+1, 1):
            points.append((idx, y))
            if y != 0: 
                points.append((idx,-y))

        for idx in range(-y, y+1, 1):
            points.append((idx, x))
            if x != 0: 
                points.append((idx,-x))

        if (d < 0):
            d += 2 * x + 1
        else:
            d += 2 * (x - y) + 1
            y -= 1

        x += 1

        if (y < x):
            break
    # 新增去重逻辑,保持原有坐标顺序
    seen = set()
    unique_points = []
    for p in points:
        if p not in seen:
            seen.add(p)
            unique_points.append(p)
    return unique_points

方案2:逻辑层根治重复

核心思路是每个y值只绘制一次水平扫描线,从根源避免重复添加,性能更好:

def get_filled_circle(radius):
    d = (5 - radius * 4) / 4.0
    x = 0
    y = radius
    points = []
    processed_y = set()  # 记录已经绘制过的y值,避免重复绘制

    while True:
        # 绘制y和-y的水平线段,仅在y首次出现时绘制
        if y not in processed_y:
            for idx in range(-x, x + 1):
                points.append((idx, y))
                if y != 0:
                    points.append((idx, -y))
            processed_y.add(y)
            processed_y.add(-y)

        # 绘制x和-x的水平线段,x逐轮递增天然不会重复
        for idx in range(-y, y + 1):
            points.append((idx, x))
            if x != 0:
                points.append((idx, -x))

        if d < 0:
            d += 2 * x + 1
        else:
            d += 2 * (x - y) + 1
            y -= 1

        x += 1
        if y < x:
            break

    return points

修复后再绘制就不会出现!标记的重复点了,填充的圆形完全符合预期。

内容的提问来源于stack exchange,提问作者cyrus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 10:39:15