monica bach
monica bach

Reputation: 41

Recursive rainbow-colored circles around each other

I'm trying to change the color and # of circles shown on the screen. So far, I've figured out how to make all of them different colors in a recursive pattern, but I need help finding out how to add more. Attached is what I have versus what I need to achieve.

my code

import turtle
import colorsys

def draw_circle(x,y,r,color):
    turtle.seth(0)
    turtle.up()
    turtle.goto(x,y-r)
    turtle.down()
    turtle.fillcolor(color)
    turtle.begin_fill()
    turtle.circle(r)
    turtle.end_fill()

def draw_recursive_circles(x,y,r,color,n):
    if n == 0:
        return
    draw_circle(x,y,r,color)
    colors = ['red','orange','yellow','green','blue','purple']
    i = 0
    for angle in range(30,360,60):
        turtle.up()
        turtle.goto(x,y)
        turtle.seth(angle)
        turtle.fd(r*2)
        draw_recursive_circles(turtle.xcor(),turtle.ycor(),r/3,colors[i],n-1)
        i += 1

turtle.tracer(0)
turtle.hideturtle()
turtle.speed(0)
draw_recursive_circles(0,0,100,'red',5)
turtle.update()

What I need to achieve

What I have so far

Upvotes: 0

Views: 492

Answers (1)

cdlane
cdlane

Reputation: 41872

You import colorsys but never use it -- this is a clue that you're supposed to generate colors based on angles and not a fixed list of colors. The reason for the import is that turtle's RGB-based colors are the wrong model for our needs, so we want a more appropriate model, like HSV (where we only really care about H/hue), and have it convert those values to RGB.

The number of satellites is determined by your range call:

for angle in range(30,360,60):

Which for this drawing should be more like:

for angle in range(0, 360, 30):

As there are twelve satellites and 360 / 30 is 12. Finally, we need to do proper accounting such that whenever we change a position or heading, in order to do recursive drawing, we need to restore the original values on exit. Below is my simplified example solution to this problem:

from turtle import Screen, Turtle
from colorsys import hsv_to_rgb

def draw_circle(radius):
    y = turtle.ycor()  # save position & heading
    heading = turtle.heading()

    turtle.fillcolor(hsv_to_rgb(heading / 360, 1.0, 1.0))

    turtle.sety(y - radius)
    turtle.setheading(0)

    turtle.begin_fill()
    turtle.circle(radius)
    turtle.end_fill()

    turtle.sety(y)  # restore position & heading
    turtle.setheading(heading)

def draw_recursive_circles(radius, n):
    if n == 0:
        return

    draw_circle(radius)

    if n > 1:
        heading = turtle.heading()  # save heading

        for angle in range(0, 360, 30):
            turtle.setheading(angle)
            turtle.forward(radius * 2)

            draw_recursive_circles(radius / 5, n - 1)

            turtle.backward(radius * 2)

        turtle.setheading(heading)  # restore heading

screen = Screen()
screen.tracer(False)

turtle = Turtle(visible=False)
turtle.penup()

draw_recursive_circles(150, 4)

screen.update()
screen.tracer(True)
screen.exitonclick()

enter image description here

I've intentionally kept the pen up to simplifiy my example so only filled portions of the circles are shown. Putting back the surrounding outlines I leave as an exercise for you.

The center circle is not the right color. Fixing this is a simple matter of setting the turtle's heading prior to the initial call to draw_recursive_circles()

Upvotes: 1

Related Questions