遍历同心圆中的每个像素

问题描述

我试图遍历每个像素坐标,从 (0,0) 开始,以便在它们不重叠的最近偏移处融合两个像素化形状。

直到现在,我一直在使用同心正方形,这确实很容易做到,但最终可能会将嫁接图像放置得更远。然后我实现了 Bresenham 圆算法如下:

def generate_offsets(maxRadius : int):
    """Generate x and y coordinates in concentric circles around the origin
    Uses Bresenham's Circle Drawing Algorithm
    """
    
    for radius in range(maxRadius):
        x = 0
        y = radius
        d = 3 - (2 * radius)
        while x < y:
        
            yield x,y
            yield y,x
            yield y,-x
            yield x,-y
            yield -x,-y
            yield -y,-x
            yield -y,x
            yield -x,y
            
            if d < 0:
                d += (4 * x) + 6
            else:
                d += (4 * (x-y)) + 10
                y -= 1
            
            x += 1

然而,这样做的缺点是不检查某些像素偏移。我找到的所有填充孔洞的解决方案都建议跟踪从 0,0 到像素的整条线,这在这里会非常浪费。

如何在不重新访问任何像素的情况下修复漏洞?


这是一个显示所述孔的示例,它代表每个圆或半径 1-9。已探索像素为 #,未探索像素为 . :

....................
....................
........#####.......
......#########.....
.....###########....
....#..#######..#...
...##..#.###.#..##..
...####.#####.####..
..####.#.###.#.####.
..#######.#.#######.
..########.########.
..#######.#.#######.
..####.#.###.#.####.
...####.#####.####..
...##..#.###.#..##..
....#..#######..#...
.....###########....
......#########.....
........#####.......
....................

更新:这是我当前的解决方案,它确实填满了整个圆圈,但存储的状态比我想要的多得多:

import itertools
def generate_offsets(minRadius : int = 0,maxRadius : int = 3_750_000):
    """Generate x and z coordinates in concentric circles around the origin
    Uses Bresenham's Circle Drawing Algorithm
    """
    def yield_points(x,y):
        
            yield x,y
            yield x,y
            
            if x != y:
                yield y,x
                yield y,-x
                yield -y,x
    
    def yield_circle(radius,prevIoUsCircle):
        x = 0
        y = radius
        d = 3 - (2 * radius)
        while x < y:
        
            for point in yield_points(x,y):
                if point not in prevIoUsCircle:
                    yield point
            
            if d < 0:
                d += (4 * x) + 6
            else:
                d += (4 * (x-y)) + 10
                for point in itertools.chain(yield_points(x + 1,y),yield_points(x,y - 1)):
                    if point not in prevIoUsCircle:
                        yield point
                y -= 1
            
            x += 1
    
    prevIoUsCircle = [(0,0)]
    for radius in range(minRadius,maxRadius):
    
        circle = set()
        for point in yield_circle(radius,prevIoUsCircle):
            if point not in circle:
                yield point
                circle.add(point)
        
        prevIoUsCircle = circle

这是迄今为止我在内存和处理方面找到的最平衡的解决方案。它只记住前一个圆圈,这将冗余率(像素访问两次的比率)从没有任何内存的大约 50% 降低到大约 1.5%

解决方法

我的头顶.....

生成一组坐标。在探索时,保持访问的一组坐标。集合之间的差异将是未访问的坐标。如果您不想处理之外的像素,也许可以跟踪 x 和 y 极值以进行比较 - 也许像字典一样:{each_row_visited:max_and_min_col_for that row,}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...