2

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(),

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:

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).

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?

  • Are you looking for a reason beyond the one in the comment? Also, the former is supposedly better, not the latter. – jonrsharpe Apr 29 '14 at 20:53
  • Exactly, I don't see how the two versions are different in terms of approximation error (after considering a few simple examples).Thanks for catching a semantic error, now fixed. – Алексей Apr 29 '14 at 20:58
  • Not that it answers your question about *why* one is better than the other, but I'd like to point out that this is [already implemented anyway](https://docs.python.org/2.7/library/turtle.html#turtle.circle). – 2rs2ts Apr 29 '14 at 21:38
  • Is the source code for [this implementation](https://docs.python.org/2.7/library/turtle.html#turtle.circle) published somewhere? -- it might give some clues as to the merits of approximations proposed in my original question. – Алексей Apr 29 '14 at 22:15

2 Answers2

1

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:

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

enter image description here

Detail #1

enter image description here

Detail #2

enter image description here

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. What criteria do you consider important?

cdlane
  • 40,441
  • 5
  • 32
  • 81
0

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.

Ryan Teo
  • 59
  • 2