gpt4 book ai didi

python - 遍历同心圆中的每个像素

转载 作者:行者123 更新时间:2023-12-04 11:39:28 26 4
gpt4 key购买 nike

我试图遍历每个像素坐标,从 (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
yield -x, -y
yield -x, y

if x != y:
yield y, x
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,} .

I would prefer a solution that doesn't expand in memory as time progresses !


而不是制作越来越大的圆圈希望填满圆盘:
  • 使用 Bresenham 算法确定具有所需半径的点
  • 找到每个 x 的最小和最大 y 值(反之亦然)
  • 使用这些极值产生极值之间的所有点
    从 pprint 导入 pprint
    from 操作符导入 itemgetter
    从 itertools 导入 groupby
    X = itemgetter(0)
    Y = itemgetter(1)

  • 此函数修改自 question in a different forum
    def circle(radius):
    '''Yield (x,y) points of a disc

    Uses Bresenham complete circle algorithm
    '''
    # init vars
    switch = 3 - (2 * radius)
    # points --> {x:(minY,maxY),...}
    points = set()
    x = 0
    y = radius
    # first quarter/octant starts clockwise at 12 o'clock
    while x <= y:
    # first quarter first octant
    points.add((x,-y))
    # first quarter 2nd octant
    points.add((y,-x))
    # second quarter 3rd octant
    points.add((y,x))
    # second quarter 4.octant
    points.add((x,y))
    # third quarter 5.octant
    points.add((-x,y))
    # third quarter 6.octant
    points.add((-y,x))
    # fourth quarter 7.octant
    points.add((-y,-x))
    # fourth quarter 8.octant
    points.add((-x,-y))
    if switch < 0:
    switch = switch + (4 * x) + 6
    else:
    switch = switch + (4 * (x - y)) + 10
    y = y - 1
    x = x + 1
    circle = sorted(points)
    for x,points in groupby(circle,key=X):
    points = list(points)
    miny = Y(points[0])
    maxy = Y(points[-1])
    for y in range(miny,maxy+1):
    yield (x,y)
    那应该最小化状态。从圆圈创建光盘时会有一些重复/重新访问 - 我没有尝试量化这一点。

    结果...
    def display(points,radius):
    ''' point: sequence of (x,y) tuples, radius: int
    '''
    not_visited, visited = '-','█'

    # sort on y
    points = sorted(points,key=Y)

    nrows = ncols = radius * 2 + 1 + 2

    empty_row = [not_visited for _ in range(ncols)] # ['-','-',...]

    # grid has an empty frame around the circle
    grid = [empty_row[:] for _ in range(nrows)] # list of lists
    # iterate over visited points and substitute symbols
    for (x,y) in points:
    # add one for the empty row on top and colun on left
    # add offset to address negative coordinates
    y = y + radius + 1
    x = x + radius + 1
    grid[y][x] = visited

    grid = '\n'.join(' '.join(row) for row in grid)

    print(grid)
    return grid

    for r in (3,8):
    points = circle(r) # generator/iterator
    grid = display(points,r)
    - - - - - - - - -
    - - - █ █ █ - - -
    - - █ █ █ █ █ - -
    - █ █ █ █ █ █ █ -
    - █ █ █ █ █ █ █ -
    - █ █ █ █ █ █ █ -
    - - █ █ █ █ █ - -
    - - - █ █ █ - - -
    - - - - - - - - -
    - - - - - - - - - - - - - - - - - - -
    - - - - - - - █ █ █ █ █ - - - - - - -
    - - - - - █ █ █ █ █ █ █ █ █ - - - - -
    - - - - █ █ █ █ █ █ █ █ █ █ █ - - - -
    - - - █ █ █ █ █ █ █ █ █ █ █ █ █ - - -
    - - █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ - -
    - - █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ - -
    - █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ -
    - █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ -
    - █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ -
    - █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ -
    - █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ -
    - - █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ - -
    - - █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ - -
    - - - █ █ █ █ █ █ █ █ █ █ █ █ █ - - -
    - - - - █ █ █ █ █ █ █ █ █ █ █ - - - -
    - - - - - █ █ █ █ █ █ █ █ █ - - - - -
    - - - - - - - █ █ █ █ █ - - - - - - -
    - - - - - - - - - - - - - - - - - - -

    关于python - 遍历同心圆中的每个像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67949646/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com