Python 2.7中的海龟图形:绘制弧形

2 投票
2 回答
5269 浏览
提问于 2025-04-18 04:48

在《Python软件设计》的第4章第4.12节的练习4.1(c)中,提到了一种新的arc()函数版本,

def arc(t, r, angle):
    """Draws an arc with the given radius and angle.
    t: Turtle
    r: radius
    angle: angle subtended by the arc, in degrees
    """

    arc_length = 2 * math.pi * r * abs(angle) / 360
    n = int(arc_length / 4) + 1
    step_length = arc_length / n
    step_angle = float(angle) / n

    # making a slight left turn before starting reduces
    # the error caused by the linear approximation of the arc
    lt(t, step_angle/2)
    polyline(t, n, step_length, step_angle)
    rt(t, step_angle/2)

说这个版本比第4.7节中的原始版本要“好”。

def arc(t, r, angle):
    arc_length = 2 * math.pi * r * angle / 360
    n = int(arc_length / 3) + 1
    step_length = arc_length / n
    step_angle = float(angle) / n
    polyline(t, n, step_length, step_angle)

(你可以在这里找到一些子程序的代码,比如polyline()这里。)

我想弄明白为什么前面的版本更好,特别是用什么标准来衡量。我们怎么定义我们要逼近的真正圆形呢?有什么想法吗?

2 个回答

0

我自己也没法解释清楚,直到我试着画出来。你可以想象一下,转动半步的角度大概可以把弧长一分为二。通过在中间走动,这就像是对多出来的区域进行粗略的修正,既增加又减少了一些面积。

1

让我们来进行一个比较。我们将使用 turtle.circle() 作为一个标准,然后用两个 arc() 函数来画360度的弧(也就是圆),一个的半径比标准小3个像素,另一个的半径比标准大3个像素:

import math
from turtle import Turtle, Screen

def polyline(t, n, length, angle):
    """Draws n line segments.

    t: Turtle object
    n: number of line segments
    length: length of each segment
    angle: degrees between segments
    """
    for _ in range(n):
        t.fd(length)
        t.lt(angle)

def arc2(t, r, angle):
    """Draws an arc with the given radius and angle.
    t: Turtle
    r: radius
    angle: angle subtended by the arc, in degrees
    """

    arc_length = 2 * math.pi * r * abs(angle) / 360
    n = int(arc_length / 4) + 1
    step_length = arc_length / n
    step_angle = float(angle) / n

    # making a slight left turn before starting reduces
    # the error caused by the linear approximation of the arc
    t.lt(step_angle/2)
    polyline(t, n, step_length, step_angle)
    t.rt(step_angle/2)

def arc1(t, r, angle):
    arc_length = 2 * math.pi * r * angle / 360
    n = int(arc_length / 3) + 1
    step_length = arc_length / n
    step_angle = float(angle) / n
    polyline(t, n, step_length, step_angle)

screen = Screen()
screen.setup(500, 500)
screen. setworldcoordinates(-250, -50, 250, 450)

thing0 = Turtle()
thing0.circle(200, steps=60)

thing1 = Turtle()
thing1.color("red")
thing1.penup()
thing1.goto(0, 3)
thing1.pendown()
arc1(thing1, 197, 360)

thing2 = Turtle()
thing2.color("green")
thing2.penup()
thing2.goto(0, -3)
thing2.pendown()
arc2(thing2, 203, 360)

screen.exitonclick()

完整的圆

这里输入图片描述

细节 #1

这里输入图片描述

细节 #2

这里输入图片描述

我觉得第4.12节的弧(绿色)看起来比第4.7节的弧(红色)更好,因为绿色的弧边缘更平滑,始终保持在离标准圆3个像素的距离,而红色的弧则时远时近。你认为哪些标准比较重要呢?

撰写回答