Thomas Fleming
Thomas Fleming

Reputation: 51

Drawing Circles extremely inconsistent?

For a school project, I'm using Python Turtle to make an "avatar". I have curly hair, so I wrote some code to draw a black half-circle, every 10-ish degrees it stops, and makes a much smaller circle of the same color, then resumes.

The code works? It does what it's supposed to do for the first 3 smaller circles, but it seems to be random on the 4th smaller circle. I've even set the degrees to draw the half-circle to 10000 and it only completed the 4th smaller circle by 3/4ths.

import turtle
t = turtle.Turtle() #defining Turtle

def drawHair():
    ##debug, getting turtle to needed pos.
    t.color("Moccasin")
    for x in range (90):
        t.forward(2.5)
        t.left(1)
    t.setheading(90)
    ##

    t.color("Black")
    cTime = 0                           #"Timer" to determine a smaller "Curl"
    for x in range (180):               #SUPPOSED to draw a half-circle
        t.forward(2.5)                  #
        t.left(1)                       #
        cTime = cTime + 1               ##For every "Degree" in the main half-circle,
                                        ##add 1 to the "Timer"
        print("circle = " + str(cTime)) #debug
        if cTime == 10:                 #If "Timer has reached it's limit"
            cTime = 0                   #Reset timer
            for x in range (360):       #Draw a full, smaller circle
                t.forward(-0.4)         #
                t.left(1)               #

I know this is more complicated than it should be. I simply want to know why this problem happens and how to fix it.

EDIT : https://i.sstatic.net/z9kF6.jpg (Proof)

Upvotes: 2

Views: 667

Answers (2)

cdlane
cdlane

Reputation: 41872

Tne problem may be that you're drawing circles that are too detailed for repl.it -- although your code should work, even Python turtle's own circle() function uses only 60 segments, not 360, to draw a circle. Even less for small circles.

Here's a rework of your code to draw all your circles in fewer segments, synchronized with your desire to draw the smaller circles every 10 degrees:

import turtle

def drawHair():
    # get turtle to needed position
    t.color("Moccasin")

    for x in range(15):
        t.forward(15)
        t.left(6)

    t.color("Black")

    for x in range(36):  # draw a half-circle
        t.forward(12.5)
        t.left(5)

        if x % 2 == 0:  # every other segment of the outer circle
            for _ in range(72):  # Draw a full, smaller circle
                t.forward(-2)
                t.left(5)

    t.color("Moccasin")  # finish the face outline

    for x in range(15):
        t.forward(15)
        t.left(6)

    t.hideturtle()

t = turtle.Turtle()

drawHair()

turtle.done()

I seems to work on repl.it for me. (Though repl.it does have lengthy pauses.) And the circles still appear round despite the reduced segments:

enter image description here

I assumed that you weren't allowed to use the turtle.circle() method, but if you can, as @Sweeper assumes, then this becomes a much simpler program:

import turtle

def drawHair():
    # get turtle to needed position
    t.color("Moccasin")
    t.circle(143, 90)
    t.color("Black")

    for x in range(18):  # draw a half-circle
        t.circle(143, 5)
        t.circle(-23)  # draw a full, smaller circle
        t.circle(143, 5)

    t.color("Moccasin")
    t.circle(143, 90)
    t.hideturtle()

t = turtle.Turtle()

drawHair()

turtle.done()

You'll see the circles are slightly cruder than my first example but you can tune this using the steps parameter of turtle.circle().

Upvotes: 1

Sweeper
Sweeper

Reputation: 271625

You are doing way too many draws, which repl.it seems to not like. There is actually a circle method in Turtle that draws circles (and semicircles) for you! This is a lot faster than drawing it with for loops.

Using this, and a bit of maths, I have come up with this code:

import turtle
from math import cos, sin, pi
t = turtle.Turtle() #defining Turtle

def drawHair():
    ##debug, getting turtle to needed pos.
    t.color("Moccasin")
    t.radians()
    t.setheading(-pi / 2)
    t.circle(140, extent=pi) # bottom semi circle
    t.color("Black")
    t.circle(140, extent=pi) # top semi circle
    for x in range(19):
        t.penup()
        t.goto(cos(x*pi/18)*180+140, sin(x*pi/18)*180) # position for each curl
        t.setheading(x*pi/18 + pi/2)
        t.pendown()
        t.circle(20)
drawHair()

I've basically used the parametric form of the equation for a circle. This is the result:

enter image description here

Upvotes: 1

Related Questions