像素网格中的圆形

4

如何使用Python在像素网格中绘制圆形C((x,y),r),已知圆心(x,y)和半径r?假设像素网格足够大即可。


你想输出一个图像文件,还是创建一个交互式应用程序?如果是交互式的,是为了数据可视化还是游戏? - loopbackbee
1
@goncalopp 我想要一个包含 01 的二维数组,其中 1 表示圆的位置。 - user4175155
请查看中点圆算法。如果您在实现细节方面遇到困难,请告诉我们。 - Falko
@Falko 非常感谢。 - user4175155
如果你想要画一个平滑的圆,可以看一下夏林·吴的快速抗锯齿圆和椭圆算法。该网站上的代码是用Pascal编写的,但翻译成Python应该不会太难。值得一提的是,吴的线条算法是绘制抗锯齿线条的标准算法;他的圆形算法则不太为人所知。 - PM 2Ring
2个回答

5

这是Python语言实现的RosettaCode中点圆算法

def circle(self, x0, y0, radius, colour=black):
    f = 1 - radius
    ddf_x = 1
    ddf_y = -2 * radius
    x = 0
    y = radius
    self.set(x0, y0 + radius, colour)
    self.set(x0, y0 - radius, colour)
    self.set(x0 + radius, y0, colour)
    self.set(x0 - radius, y0, colour)

    while x < y:
      if f >= 0: 
        y -= 1
        ddf_y += 2
        f += ddf_y
        x += 1
        ddf_x += 2
        f += ddf_x    
        self.set(x0 + x, y0 + y, colour)
        self.set(x0 - x, y0 + y, colour)
        self.set(x0 + x, y0 - y, colour)
        self.set(x0 - x, y0 - y, colour)
        self.set(x0 + y, y0 + x, colour)
        self.set(x0 - y, y0 + x, colour)
        self.set(x0 + y, y0 - x, colour)
        self.set(x0 - y, y0 - x, colour)
        Bitmap.circle = circle

        bitmap = Bitmap(25,25)
        bitmap.circle(x0=12, y0=12, radius=12)
        bitmap.chardisplay()

最好将链接文本稍微具体化,以防止链接腐败。例如,“这是用Python编写的RosettaCode Midpoint circle algorithm”。确实,RosettaCode是一个相当稳定的网站,但你永远不知道... 而且在Stack Exchange网站上养成这种习惯很好。 - PM 2Ring
@PM2Ring 谢谢您的评论。我会修复它。 - A.M.
如果我想在matplotlib上实现这个怎么办? - FaCoffee

4
假设你想“完成任务”(而不是学习光栅图形算法),只需使用Pillow: (链接)
from PIL import Image, ImageDraw
image = Image.new('1', (10, 10)) #create new image, 10x10 pixels, 1 bit per pixel
draw = ImageDraw.Draw(image)
draw.ellipse((2, 2, 8, 8), outline ='white')
print list(image.getdata())

输出:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

范围为0..255,因为Pillow即使对于每个像素只有1位的图像(这样更有效率),也会存储一个字节。
如果您想将范围设置为0..1,那么可以通过除以255来实现:
[x/255 for x in image.getdata()]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接