【问题标题】:Creating repeated circles x and y axis python创建重复的圆圈x和y轴python
【发布时间】:2012-11-20 19:30:23
【问题描述】:

我希望在 python 中生成这种模式:

这是我生成的代码,它生成了 5 个完整的圆圈:

def fdShape():
    win = GraphWin("pdShape",200,200)
    centre = Point(20,100)
    for x in range(5):
        circle = Circle(centre, 20)
        circle.setFill("red")
        centre = Point((centre.getX() + 40),100)
        circle.draw(win)

但是,我对如何获得上方和下方的半圆感到困惑。有人有想法么?我不确定如何让代码沿 y 轴重复。

非常感谢任何帮助。

谢谢。

【问题讨论】:

  • 您使用的是什么图形模块? TkInter 没有具有这些名称的类,PyQt/PySide、PyGtk+、wxPython 也没有……LEDA 的 Python 包装器有 GraphWin,但没有 Circle……我很难过。
  • 嘿 @abarnert,这是我正在使用的图形模块:poolem.myweb.port.ac.uk/intprog/graphics.py John Zelle - Python 编程:计算机科学导论
  • 好的,在快速浏览了那个库之后,我已经稍微完善了我的答案。

标签: python python-3.x python-2.7


【解决方案1】:

这是一个使用 Python 的海龟图形的解决方案,它可能不像你想象的那样工作:

from turtle import Turtle, Screen, Shape

COUNT = 5
SIZE = 400
RADIUS = SIZE / COUNT
STAMP_UNIT = 20

screen = Screen()

circle_in_square = Shape("compound")
turtle = Turtle(shape="square")
circle_in_square.addcomponent(turtle.get_shapepoly(), "white")
circle_in_square.addcomponent([(-10, 10), (-10, -10)], "black")
circle_in_square.addcomponent([(10, -10), (10, 10)], "black")

turtle.shapesize(SIZE / STAMP_UNIT * 1.01)
turtle.stamp()  # stamp background to get a border

turtle.shape("circle")
turtle.shapesize(1.0)
circle_in_square.addcomponent(turtle.get_shapepoly(), "red", "black")

screen.register_shape("squircle", circle_in_square)
turtle.shape("squircle")
turtle.shapesize(RADIUS / STAMP_UNIT)
turtle.penup()

for y in range(1 - COUNT, 1):
    for x in range(-COUNT//2 + 1, COUNT//2 + 1):
        for sign in (1, -1):
            turtle.goto(x * RADIUS, y * RADIUS/2 * sign)
            turtle.stamp()

screen.exitonclick()

它首先创建一个我称之为 squircle 的图章,它是一个白色方块上的红色圆圈,顶部和底部有黑色边框:

然后它会在水平方向上并排,在垂直方向上重叠 50%:

加了一点外边框。这是我的“通过加盖更好地生活”系列的一部分(与您的解决方案和其他解决方案的绘图相反)尝试回答。

【讨论】:

    【解决方案2】:

    不知道您使用的是什么图形库,很难给出具体的答案。但有四种可能:

    1. 库可能有一个类似于Circle 类的Arc 类,或者可能是一种限制Circle 对象仅显示(填充)弧的方法,或类似的东西。如果是这样,为了得到你的半圆,你可以使用 Arc(centre, 20, -math.pi/2, math.pi/2)Arc(centre, 20, math.pi/2, 3*math.pi/2) 之类的东西。

    2. 库可能有办法设置显式边界框来截断任何对象。所以,你会这样做:bb = circle.getBoundingBox(); bb.top = (bb.top + bb.bottom) / 2; circle.setBoundingBox(bb)

    3. 该库可能没有任何明确的方法来执行此操作,但可以让您在 Z 顺序中的其他事物之上绘制事物。所以,首先你画五个完整的圆圈穿过顶部,然后你画一个白色的大矩形,覆盖所有圆圈的下半部分。 (如果有办法设置边框颜色和填充颜色,那甚至可以免费为您提供这些矩形线。)

    4. 库可能根本没有办法做到这一点,在这种情况下,您必须使用不同的库。

    同时,对于“我如何让代码沿 y 轴重复”,这只是您已有的循环之外的另一个循环。像这样的:

    def fdShape():
        win = GraphWin("pdShape",200,200)
        centre = Point(20,100)
        for y in range(9):
            for x in range(5):
                circle = Circle(centre, 20)
                circle.setFill("red")
                centre = Point((centre.getX() + 40), centre.getY())
                circle.draw(win)
            centre = Point(20, centre.getY() + 40)
    

    但是,最好只从 x 和 y 创建点,而不是显式添加它们:

        for y in range(9):
            for x in range(5):
                centre = Point(x * 40 + 20, y * 40 + 60)
                circle = Circle(centre, 20)
                circle.setFill("red")
                circle.draw(win)
    

    the library link you gave in the comments,似乎没有办法做到1或2。完整的文档在一本我没有的教科书里,但是网上有reference docs,代码是很简单。 Circle 和它的任何父类都没有任何方法来指定弧或要截断的框。 (有一个边界框,但将其切成两半只会导致压扁椭圆的高度为原圆的一半,而不是半圆。)

    而且大概你正在学习需要这个库的课程,所以 4 不是一个选项。

    剩下 3。这意味着您实际上将不得不稍微改变循环。像这样的:

        for y in range(4):
            # draw row of circles y
            # draw row 8-y
            # draw rectangle y
            # draw rectangle 8-y
        # draw row of circles 4
    

    请注意,矩形 3 和矩形 5 将是同一个,因此绘制两者有点浪费,但我认为在这种情况下,保持代码更简单是值得浪费的。如果你的老师不同意,应该很容易弄清楚如何重构代码。

    最后,说到重构代码,鉴于您必须使用不同的值执行两次“绘制一排圆”,您可能应该将其转换为一个函数,同样用于“绘制矩形”。那么上面的伪代码就变成了真正的代码:

        for y in range(4):
            drawRowOfCircles(win, y)
            drawRowOfCircles(win, 8-y)
            drawRectangle(win, y)
            drawRectangle(win, 8-y)
        drawRowOfCircles(win, 4)
    

    【讨论】:

      【解决方案3】:

      看看python中的turtle包。在turtle 中,您可以指定circle 以及绘制它的角度范围。当然,你只需要弄清楚你的圈子在哪里集中并迭代到你的内心满足!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-21
        • 2021-09-19
        相关资源
        最近更新 更多