两个基于三角学的海龟代码没有给出相似的输出

Two trigonometry-based turtle codes not giving similar output

这是我第一次发帖提问。 我在创建涉及余弦的代码时遇到问题,而且我没有收到预期的结果。更令人困惑的是,这两个代码应该创建相似的图像(稍后解释)。有什么想法吗?

在下面的代码中,这些变量代表: Y 是一个计数器,确保代码仅在生成指定数量的半径之前运行。 W是随机生成的颜色。 Z 是从 0 度开始的角度转弯。 (由于turtle.home,乌龟的角度重置)。 相邻是从中心到一条线的最小长度。 半径是从中心突出的线的数量。

def Triangle(Radi, Adjacent):
y = 0
if (Radi) % 1 == 0:
    while (Radi) > y:
        y = y + 1
        w = randhex()
        z = 360/(Radi)*y
        turtle.left(z+30)
        turtle.color(w)
        if z > 300:
            turtle.forward(Adjacent/math.cos(math.pi*(60 - (z - 300))/180))
        elif z > 240:
            turtle.forward(Adjacent/math.cos(math.pi*(z - 240)/180))
        elif z > 180:
            turtle.forward(Adjacent/math.cos(math.pi*(60 - (z - 180))/180))
        elif z > 120:
            turtle.forward(Adjacent/math.cos(math.pi*(z - 120)/180))
        elif z > 60:
            turtle.forward(Adjacent/math.cos(math.pi*(60 - (z - 60))/180))
        else:
            turtle.forward(Adjacent/math.cos(math.pi*z/180))
        turtle.home()

上面是我的第一个代码,它似乎有效,在输入 Triangle(100,180) 时给出这些结果(请注意 randhex() 是一个生成随机颜色的自定义函数)。

Triangle(100,180) results.

如果我的变量命名创意令人讨厌,我深表歉意。 在此代码中,counter 表示 'y',angle 表示前面代码中的 'z' 这是我的第二个代码:

def Polygon(Radi, Adjacent, Sides):
    counter = 0
    if Sides % 1 != 0 or Sides == 2 or Sides <= 0:
        print ("INVALID")
    elif Sides == 1:
        while Radi > counter:
            counter = counter + 1
            colour = randhex()
            turn = 360/Radi*counter
            turtle.left(turn)
            turtle.color(colour)
            turtle.forward(Adjacent)
            turtle.home()
    else:
        while Radi > counter:
            counter = counter + 1
            colour = randhex()
            turn = 360/Radi*counter
            turtle.left(turn)
            turtle.color(colour)
            segment = str(counter/Radi*Sides*2)
            position = segment.index('.')
            test = int(segment[:position])
            if test % 2 == 1:
                length = Adjacent/math.cos(math.pi*(turn - (360 - 360/Sides*((test+1)/2)))/180)
                turtle.forward(length)
            else:
                length = Adjacent/math.cos(math.pi*(180/Sides - (turn - (360 - 180/Sides*(test+1))))/180)
                turtle.forward(length)
            turtle.home()

以上是我的第二个代码,这是我正在努力处理的代码。再次为我的变量名令人讨厌和一些数学没有简化而道歉。当我保持原样时,我发现我的想法更容易理解。以下是输入 Polygon(180,100,3).

后我的第二个代码的结果

Polygon(180,100,3) results.

如您所见,事情并没有完全按照我的计划进行。 我还应该注意,我尝试将数字替换为其中一个代码给出不同行长度的代码。有时他们甚至朝相反的方向发展(因为结果是负数)。我在 Google 计算器上做了这个,但似乎两个代码都会给出相同的答案,但它们对应于第二个代码输出的内容,而不是第一个。

如果你想让我解释任何事情,请发表评论。 但如果事实证明我的代码是错误的(我相信),请你指出我需要做的事情。 我将不胜感激。

您的代码太复杂,无法调试。毫无用处的变量名、缺少注释和过长的方程式都让人难以阅读。

如果我们考虑 Is there an equation to describe regular polygons? 这个答案中建议的等式,那么您的原始三角形代码将简化为:

import math
import turtle

def randhex():
    """ substitute random color generator here """
    return 'red'

def triangle(radii, adjacent):

    if radii % 1 != 0:  # only whole numbers (int or float) allowed
        return

    counter = 1

    while counter <= radii:

        angle = counter * (2 * math.pi / radii)
        turtle.setheading(angle)

        colour = randhex()
        turtle.color(colour)

        radius = adjacent / math.cos(angle % (math.pi / 1.5) - math.pi / 3)

        turtle.forward(radius)
        turtle.backward(radius)

        counter += 1

turtle.radians()  # avoid individual conversions, switch to radians

triangle(100, 180)

turtle.exitonclick()

一般的多边形解决方案只需进行一些更改即可实现:

import math
import turtle

def randhex():
    """ substitute random color generator here """
    return 'red'

def polygon(radii, adjacent, sides):

    if radii % 1 != 0:  # only whole numbers (int or float) allowed
        return

    if sides % 1 != 0 or sides == 2 or sides <= 0:
        return

    counter = 1

    while counter <= radii:

        angle = counter * (2 * math.pi / radii)
        turtle.setheading(angle)

        colour = randhex()
        turtle.color(colour)

        if sides == 1:  # special case, a circle
            radius = adjacent
        else:
            radius = adjacent / math.cos(angle % (math.pi / (sides / 2)) - math.pi / sides)

        turtle.forward(radius)
        turtle.backward(radius)

        counter += 1

turtle.radians()  # avoid individual conversions, switch to radians

polygon(100, 180, 3)

turtle.exitonclick()

polygon(100, 90, 5) 看起来像: