【问题标题】:Using turtle in Python to draw six-pointed stars with different side lengthsPython中使用turtle绘制不同边长的六角星
【发布时间】:2017-03-05 16:19:37
【问题描述】:

希望我能很好地解释这一点。我目前正在使用辅助函数在python的海龟图形窗口中绘制一个六角星。首先,我们必须创建一个函数来绘制一个三角形。这是我的代码:

    import turtle

    wn = turtle.Screen()
    tess = turtle.Turtle()
    tess.speed(30)


   def triangle(sz):
       for i in range(3):
         tess.fd(sz)
         tess.lt(120)

然后,我们不得不使用三角形函数来绘制一个六角星。这是我的代码:

    def sixPtdStar(sz):
       triangle(sz)
       tess.lt(90)
       tess.pu()
       tess.fd(80)
       tess.rt(90)
       tess.fd(120)
       tess.pd()
       tess.rt(180)
       triangle(sz)

现在,对我来说,这一切都很顺利。但是我们对这两个函数的测试运行的参数是 sz = 120(所以在 shell 中我们输入了 SixPtdStar(120) 并且它会运行。但是我们必须用一个新函数绘制一排星星,并且然后在另一个函数中由这些星行组成的 BOX 轮廓。这是我的代码:

    def rowOfStars(numInRow,sz):
        for i in range(numInRow):
           sixPtdStar(sz)
           tess.pu()
           tess.lt(90)
           tess.fd(80)
           tess.lt(90)


    def sqrOfRows(numInRow, sz):
        for i in range(4):
          rowOfStars(numInRow, sz)
          tess.rt(90)

虽然这完成了任务,但只有当 sz = 120 时才会这样做。对于我们在 rowOfStars 函数上运行的测试,参数应该是 (6, 72) 并且对于 sqrOfRows 函数上的测试运行,我们的参数应该是 (6, 36)。

所以我的问题是这样的。无论 sz 等于什么,我怎样才能完成这项工作?当我按原样运行它时(对于 rowOfStars 使用 (6, 72) 或对于 sqrOfRows 使用 (6, 36)),笔移动得太远了,因为三角形不再那么大了。

如果需要更多信息,请告诉我!谢谢! (我使用的是 Python 3.5.2)

【问题讨论】:

  • 非常感谢大家。我知道主要问题在于我的形状的缩放,因为我移动了多少笔以使其进入“正确”位置。还要感谢这里和那里的小调整和建议,比如使用“最快”而不是数字!非常感谢!!

标签: python graphics python-3.5 turtle-graphics


【解决方案1】:

任何使用具有尺寸的单位的地方:

tess.fd(80)
tess.fd(120) # probably should be tess.fd(sz)
tess.fd(80)

您需要按照以前从 120 (sz) 到 80 的逻辑对其进行缩放。但是,正如 @wptreanor 所提到的,由于您的星号上的点不均匀,该逻辑存在一些缺陷:

另外,您的rowOfStars() 例程并没有真正绘制一排星星(数学关闭,笔有时处于错误状态。)简单地修复缩放不会解决这个问题。最后,您的sqrOfRows() 例程在rowOfStars() 修复之前将无法工作,并且为了使其有用,您需要调整屏幕上的起始位置以便为绘图腾出空间。

以下是我为解决其中一些问题而对您的代码进行的修改。它使用稍微不同的计算方式来计算从完成下三角形到开始上三角形的定位,因此数字略有不同:

from turtle import Turtle, Screen

WIDTH_RATIO = 2 * 3**0.5 / 3  # ratio of widest point in star to edge of triangle 

def triangle(size):
    for i in range(3):
        tess.fd(size)
        tess.lt(120)

def sixPtdStar(size):
    triangle(size)
    tess.lt(30)
    tess.pu()
    tess.fd(size * WIDTH_RATIO)
    tess.lt(150)
    tess.pd()
    triangle(size)

def rowOfStars(numInRow, size):
    for i in range(numInRow):
        sixPtdStar(size)
        tess.pu()
        tess.lt(90)
        tess.fd(size * WIDTH_RATIO / 2)
        tess.lt(90)
        tess.pd()

def sqrOfRows(numInRow, size):
    tess.pu()
    halfSize = numInRow * size / 2
    tess.goto(-halfSize, halfSize)  # center on screen
    tess.pd()

    for i in range(4):
        rowOfStars(numInRow, size)
        tess.rt(90)

screen = Screen()
tess = Turtle()
tess.speed("fastest")  # numbers > 10 are all equivalent, safer to use symbols 

sqrOfRows(6, 36)

screen.exitonclick()

【讨论】:

    【解决方案2】:

    问题出在您的sixPtdStar() 函数中。

    def sixPtdStar(sz):
       triangle(sz)
       tess.lt(90)
       tess.pu()
       tess.fd(80) # here 
       tess.rt(90)
       tess.fd(120) # and here
       tess.pd()
       tess.rt(180)
       triangle(sz)
    

    如果您的函数将大小作为参数,则所有涉及运动的函数(例如forward()goto())也需要按大小进行缩放。以下代码应该可以工作:

    def sixPtdStar(sz):
       triangle(sz)
       tess.lt(90)
       tess.pu()
       tess.fd((2.0/3.0)*sz) #formerly 80
       tess.rt(90)
       tess.fd(sz) #formerly 120
       tess.pd()
       tess.rt(180)
       triangle(sz)
    

    这将确保所有向前移动都与您创建的对象的大小成正比。您需要对 rowOfStars() 函数进行类似的调整。我还注意到你的六角星不是完全对称的。您可以通过将tess.fd((2.0/3.0)*sz) 替换为tess.fd((7.0/12.0)*sz) 来解决该问题。

    【讨论】:

    • 我假设你正在逼近 sqrt(3)/3 所以 (15.0 / 26.0) 应该更接近但仍然很简单。或者 OP 可以计算:test.fd(sz * 3**0.5/3)
    猜你喜欢
    • 2018-03-24
    • 2014-08-29
    • 2014-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多