简体   繁体   English

Python 2.7中的Turtle图形:绘制圆弧

[英]Turtle graphics in Python 2.7: Drawing an arc

In Exercise 4.1(c) in Section 4.12 (Chapter 4) of Python for Software Design it is claimed that the following version of function arc() , Python for Software Design第4.12节(第4章)的练习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)

is "better" than the original one from Section 4.7: 比第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)

(You can look up the code of subroutines, such as polyline() , here ). (您可以在此处查找子程序的代码,例如polyline() )。

I'm trying to understand why the former version is better, in particular, by which metric. 我试图了解为什么以前的版本更好,尤其是按哪个指标。 How can we define the true circle we are approximating? 我们如何定义逼近的真实圆? Any ideas? 有任何想法吗?

I could not explain it to myself also until I tried to sketch it. 在尝试绘制草图之前,我也无法向自己解释。 If you can imagine it, the turn of half a step angle helps to bisect the arc length approximately. 如果可以想象,半步角转弯有助于大致将弧长平分。 By going in between, it is kind of a rough correction to both add and subtract the additional areas created. 通过介于两者之间,可以对创建的其他区域进行加法和减法,这是一种粗略的校正。

Let's have a bake-off to compare. 让我们进行比较。 We'll use turtle.circle() as an arbitrary standard and then use the two arc() routines to draw 360 degree arcs (aka circles), one 3 pixels smaller radius, one 3 pixels larger radius than our standard: 我们将使用turtle.circle()作为任意标准,然后使用两个arc()例程绘制360度弧(aka圆),半径比我们的标准小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()

Complete Circles 完整的圈子

在此处输入图片说明

Detail #1 细节#1

在此处输入图片说明

Detail #2 细节#2

在此处输入图片说明

I would say that the Section 4.12 arc (green) looks better than the Section 4.7 arc (red) as the green arc has less jaggies and stays a consistent 3 pixels away from our standard circle whereas the red arc veers closer and further. 我要说的是,第4.12弧(绿色)看起来比第4.7弧(红色)更好,因为绿色弧线的锯齿少,并且与我们的标准圆保持一致的3个像素,而红色弧线则越来越近。 What criteria do you consider important? 您认为什么标准重要?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM