【问题标题】:Drawing a complete graph of equally-spaced points on a circle's circumference with Turtle用 Turtle 在圆的圆周上绘制等距点的完整图
【发布时间】:2021-01-29 12:43:04
【问题描述】:

我正在编写一个函数,它在以原点为中心的圆的圆周上点等距点,然后在所有点之间画线。

我一直在搞乱这段代码,但我似乎无法让它按预期运行。我需要根据给定的半径和海龟中的点数制作一个圆。这是我目前所拥有的:

from turtle import *

def drawLineSeg (p, q):
    up()
    goto(p)
    down()
    goto(q)

def pntCirc (r, n):
    for i in range(1, n+1):
        up()
        goto(0,0)
        forward(r)
        down()
        dot(10)
        L.append (pos())
        right(360/n)

L = []

def clique (r, n):
    pntCirc (r, n)
    color ('blue')
    for i in range(0, len(L)):
        drawLineSeg (L[0], L[i])
        drawLineSeg (L[1], L[i])
        drawLineSeg (L[2], L[i])
        drawLineSeg (L[3], L[i])
        drawLineSeg (L[4], L[i])
        drawLineSeg (L[5], L[i])
        drawLineSeg (L[6], L[i])
        drawLineSeg (L[7], L[i])
        drawLineSeg (L[8], L[i])
        drawLineSeg (L[9], L[i])
        drawLineSeg (L[10], L[i])
        drawLineSeg (L[11], L[i])
        drawLineSeg (L[12], L[i])
        drawLineSeg (L[13], L[i])
        drawLineSeg (L[14], L[i])
        drawLineSeg (L[15], L[i])
        drawLineSeg (L[16], L[i])
        drawLineSeg (L[17], L[i])
        drawLineSeg (L[18], L[i])
        drawLineSeg (L[19], L[i])
    return

speed(50)
color ('red')
clique (300, 20)
# clique (300, 8)
# clique (300, 16) 
hideturtle()
done()

在 clique 函数中,我尝试使用 for 循环和 while 循环,这正是我需要使用它才能工作的地方;我不能再使用enumeratenumpymatplotlib 之类的技术性内容。我需要对任意数量的给定点进行这项工作,而不仅仅是我测试的 20 点。例如,当我测试 8 分时,它会抛出 IndexError。我如何用一个代码而不是硬写来做到这一点?

clique (300, 20)
# clique (300, 8)
# clique (300, 16) 

如上所述,我已对其进行硬编码,以便在使用 20 分时给我完整的结果 (this is the full model that I hard coded the function for),但如果我只是输入:

for i in range(0, len(L)):
        drawLineSeg (L[0], L[i])

I get this instead.

任何帮助将不胜感激,因为我目前陷入困境并且不知道如何从这里开始。

【问题讨论】:

  • 欢迎来到 SO!您将需要一个内部循环——对于每个点,对于列表其余部分中的每个其他点,在它们之间画一条线。你离这里很近。

标签: python python-3.x list turtle-graphics python-turtle


【解决方案1】:

在这里付出了巨大的努力。你画的是complete graph。您非常接近,只是缺少一个内部循环,这基本上是硬编码的 20 调用模拟的内容。

我们需要找到所有点的组合,所以逻辑本质上是一个嵌套循环:

for each point at index i from 0 to length(points):
    for each other point from index i + 1 to length(points):
        draw a line between the two points

虽然从中心移动海龟会起作用,但我更喜欢用数学方法计算圆圆周周围的点。一个点的公式是:

x = math.cos(angle_in_radians) * radius + center_x
y = math.sin(angle_in_radians) * radius + center_y

...但是为了我们的目的,中心被假定为0(这是一个很好的参数)。

要计算圆周上的所有点,我们可以从 0 到 360 度以 360 / n(我们要绘制的点数)的增量进行迭代,然后将角度转换为弧度并代入公式。不需要列表。

除了装饰外,我更愿意避免 from turtle import * 将太多函数带入命名空间。最好使用import turtle,然后使用turtle 前缀。我还希望创建一个 Turtle 实例并将其传递给函数,因此它不依赖于全局状态。

我还希望对所有可用旋钮使用函数参数。中心xy 会很高兴添加。

最终结果是:

import math
import turtle

def clique(t, r, n, dotsize=10, dotcolor="red", linecolor="blue"):
    for i in range(n):
        a = 360 / n * i
        x = math.cos(math.radians(a)) * r
        y = math.sin(math.radians(a)) * r
        t.color(linecolor)

        for i in range(i + 1, n):
            a = 360 / n * i
            xx = math.cos(math.radians(a)) * r
            yy = math.sin(math.radians(a)) * r
            t.goto(x, y)
            t.pendown()
            t.goto(xx, yy)
            t.penup()

        t.goto(x, y)
        t.color(dotcolor)
        t.dot(dotsize)

if __name__ == "__main__":
    t = turtle.Turtle()
    t.penup()
    t.speed("fastest")
    clique(t, 200, 7)
    turtle.exitonclick()

【讨论】:

    【解决方案2】:

    我很欣赏@ggorlen 的圆形数学方法来解决问题 (+1),但我认为从您所在的位置到您想要的位置的最短路径是通过一个嵌套循环,该循环从每个点画线到另一个点避免空行(同一点)和冗余行:

    from turtle import Screen, Turtle
    
    def drawLineSeg(p, q):
        turtle.goto(p)
        turtle.pendown()
        turtle.goto(q)
        turtle.penup()
    
    def pntCirc(r, n):
        for _ in range(1, n + 1):
            turtle.forward(r)
            turtle.dot(10)
    
            positions.append(turtle.position())
    
            turtle.backward(r)
            turtle.right(360 / n)
    
    def clique(r, n):
        pntCirc(r, n)
    
        turtle.color('blue')
    
        for start in range(len(positions) - 1):
            for end in range(start + 1, len(positions)):
                drawLineSeg(positions[start], positions[end])
    
    positions = []
    
    screen = Screen()
    
    turtle = Turtle()
    turtle.hideturtle()
    turtle.color('red')
    turtle.speed('fastest')
    turtle.penup()
    
    clique(300, 20)
    
    screen.exitonclick()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-23
      相关资源
      最近更新 更多