如何将中点圆算法“转换”为matplotlib?

时间:2016-02-21 17:34:59

标签: python algorithm matplotlib geometry rasterizing

我需要在matplotlib中实现Midpoint Circle Algorithm,以便在200x200单元格的方格网格上栅格化圆圈。另请参阅我关于该主题的other question

感谢this answer,我能够找到一些我认为完美无瑕的代码。我唯一的问题是我不知道如何整合它并修改它以确保matplotlib1内部0matplotlib之外绘制一个实心圆圈

这是我使用import numpy import matplotlib.pyplot as plt n=200 #Grid size, 4 times my visualized output in order to be able to truncate some circles empty_lattice=numpy.zeros((n,n)) #The empty 2D grid radius=int(numpy.random.uniform(30,90)) #Radius xc=int(numpy.random.uniform(0,n-radius)) #X center yc=int(numpy.random.uniform(0,n-radius)) #Y center x=0 y=radius d=3-2*radius while (x<=y): for hor in range(0,x): #This loop is my unfortunate attempt to fill the circle with 1s for ver in range(0,y): empty_lattice[xc+x][yc+y]=1 #1st octant empty_lattice[xc-x][yc+y]=1 #2nd octant empty_lattice[xc+x][yc-y]=1 #3rd octant empty_lattice[xc-x][yc-y]=1 #4th octant empty_lattice[xc+y][yc+x]=1 #5th octant empty_lattice[xc-y][yc+x]=1 #6th octant empty_lattice[xc+y][yc-x]=1 #7th octant empty_lattice[xc-y][yc-x]=1 #8th octant if (d<0): d=d+4*x+6 else: d=d+4*(x-y)+10 y=y-1 x=x+1 实现脚本的方式:

<head>

现在,这就是我所获得的,但你看到我的圆圈是空的,并且在它底部的水平线上有一个“间隙”。这个间隙发生在每个八分圆交叉处。 如何修改我的代码以填补圈子和差距?

enter image description here

修改

采用the answer provided below后,我意识到下图中绘制了两个镜像圆圈。我认为这个错误来自我的原始脚本而不是答案。我只想在每张图片中放一个圆圈。 如何摆脱此功能?

enter image description here

1 个答案:

答案 0 :(得分:1)

要消除差距,您需要将水平范围扩展一个。在您的代码中,这将是行for hor in range(0,x + 1):。我的代码采取了不同的策略。

据我了解,中点圆算法只是围绕圆周运行。所以我认为它不能轻易修改以填补内部空间。下面的代码检查第一个八分圆中的每个点,以查看该点与中心的距离是否小于或等于半径。如果它在半径范围内,则每个八分圆中的所有8个对应点都被填充。

import numpy
import matplotlib.pyplot as plt    
n=200 #Grid size, 4 times my visualized output in order to be able to truncate some circles
empty_lattice=numpy.zeros((n,n)) #The empty 2D grid
radius=int(numpy.random.uniform(30,90)) #Radius
xc=int(numpy.random.uniform(0,n-radius)) #X center
yc=int(numpy.random.uniform(0,n-radius)) #Y center
r2 = radius ** 2
for dx in range(0, radius):
    dx2 = dx ** 2
    for dy in range(0, dx + 1):
        dy2 = dy ** 2
        if (dx2 + dy2 <= r2):
            empty_lattice[xc+dx][yc+dy]=1 #1st octant
            empty_lattice[xc-dx][yc+dy]=1 #2nd octant
            empty_lattice[xc+dx][yc-dy]=1 #3rd octant
            empty_lattice[xc-dx][yc-dy]=1 #4th octant
            empty_lattice[xc+dy][yc+dx]=1 #5th octant
            empty_lattice[xc-dy][yc+dx]=1 #6th octant
            empty_lattice[xc+dy][yc-dx]=1 #7th octant
            empty_lattice[xc-dy][yc-dx]=1 #8th octant

plt.imshow(empty_lattice)
plt.show()

如果你真的想坚持使用中点圆算法,你可以画出周长,然后从中心点开始flood fill

编辑1:

摆脱了两条不必要的线。

编辑2:

上面的代码以模块化方式围绕图像边缘包裹圆圈。如果你不想这样,需要一些额外的条件:

            empty_lattice[xc+dx][yc+dy]=1 #1st octant
            if (xc - dx >= 0):
                empty_lattice[xc-dx][yc+dy]=1 #2nd octant
            if (yc - dy >= 0):
                empty_lattice[xc+dx][yc-dy]=1 #3rd octant
            if (xc - dx >= 0 and yc - dy >= 0):
                empty_lattice[xc-dx][yc-dy]=1 #4th octant
            if (yc + dx < n):
                empty_lattice[xc+dy][yc+dx]=1 #5th octant
            if (xc - dy >= 0):
                empty_lattice[xc-dy][yc+dx]=1 #6th octant
            if (yc - dx >= 0):
                empty_lattice[xc+dy][yc-dx]=1 #7th octant
            if (xc - dy >= 0 and yc - dx >= 0):
                empty_lattice[xc-dy][yc-dx]=1 #8th octant

编辑3:

我意识到原始代码出了什么问题。您的for循环涉及变量hor,但您忘记使用hor。这段代码有效。我会留给你检查指数是否为正。

x=0
y=radius
d=3-2*radius
while (x<=y):
    for hor in range(0,x + 1): #This loop is my unfortunate attempt to fill the circle with 1s
##        for ver in range(0,y):
        empty_lattice[xc+hor][yc+y]=1 #1st octant
        empty_lattice[xc-hor][yc+y]=1 #2nd octant
        empty_lattice[xc+hor][yc-y]=1 #3rd octant
        empty_lattice[xc-hor][yc-y]=1 #4th octant
        empty_lattice[xc+x][yc+hor]=1 #1st octant
        empty_lattice[xc-x][yc+hor]=1 #2nd octant
        empty_lattice[xc+x][yc-hor]=1 #3rd octant
        empty_lattice[xc-x][yc-hor]=1 #4th octant
        empty_lattice[xc+hor][yc+x]=1 #5th octant
        empty_lattice[xc-hor][yc+x]=1 #6th octant
        empty_lattice[xc+hor][yc-x]=1 #7th octant
        empty_lattice[xc-hor][yc-x]=1 #8th octant
        empty_lattice[xc+y][yc+hor]=1 #5th octant
        empty_lattice[xc-y][yc+hor]=1 #6th octant
        empty_lattice[xc+y][yc-hor]=1 #7th octant
        empty_lattice[xc-y][yc-hor]=1 #8th octant
    if (d<0):
        d=d+4*x+6
    else:
        d=d+4*(x-y)+10
        y=y-1
    x=x+1