【问题标题】:Turtle graphics in Python 2.7: Drawing an arcPython 2.7 中的海龟图形:绘制弧线
【发布时间】:2014-06-16 00:01:48
【问题描述】:

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)

比第 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()here)。

我试图了解为什么以前的版本更好,特别是哪个指标。我们如何定义我们正在逼近的真实圆?有什么想法吗?

【问题讨论】:

  • 您是否正在寻找评论中的原因之外的原因?此外,据说前者更好,而不是后者。
  • 没错,我看不出这两个版本在近似误差方面有何不同(在考虑了几个简单的例子之后)。感谢您发现语义错误,现已修复。
  • 并不是说它回答了你关于为什么一个比另一个更好的问题,但我想指出这是already implemented anyway
  • this implementation 的源代码是否在某处发布? - 它可能会为我最初的问题中提出的近似值的优点提供一些线索。

标签: python python-2.7 turtle-graphics approximation


【解决方案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 像素,而红色弧线越来越近.您认为哪些标准很重要?

【讨论】:

    【解决方案2】:

    在我尝试画草图之前,我也无法对自己解释。如果您可以想象,半步距角的转角有助于将弧长大致平分。通过介于两者之间,添加和减去创建的额外区域是一种粗略的修正。

    【讨论】:

      猜你喜欢
      • 2022-11-21
      • 2016-01-05
      • 1970-01-01
      • 2014-12-14
      • 1970-01-01
      • 2014-03-18
      • 1970-01-01
      • 1970-01-01
      • 2018-05-30
      相关资源
      最近更新 更多