I want to draw circles in 3 random colors. But in this code, used to draw the circles, the output is without color:
import turtle
window=turtle.Screen()
tess= turtle. Turtle()
import random
def getColor():
color=random.randint(1,3)
if color==1:
color="red"
elif color==2:
color=="yellow"
elif color==3:
color=="blue"
return color
print (random.randint(1,3))
def drawFace (x,y):
tess.penup()
tess.goto(x+5,y+10)
tess.circle(10)
tess.goto(x+15,y+10)
tess.circle(10)
tess.pendown()
In the getColor() function, you're not assigning to the color variable when it is yellow or blue - you're using double equal. Here's the fixed version:
def getColor():
color=random.randint(1,3)
if color==1:
color="red"
elif color==2:
color="yellow"
elif color==3:
color="blue"
return color
Secondly, you picked the pen up in the beginning of drawFace() and never put it down before finishing! Here's the fix:
def drawFace (x,y):
tess.penup()
tess.goto(x+5,y+10)
tess.pendown()
tess.circle(10)
tess.penup()
tess.goto(x+15,y+10)
tess.pendown()
tess.circle(10)
You don't need to pick random numbers to index your colors, you can randomly pick one directly with random.choice(). You need to call GetColor() and apply the color you've chosen via tess.pencolor() We also tend to think of positioning circles based on their center but Python turtle doesn't so we need to (explicitly) adjust for that as you did (implicitly) in your code:
from turtle import Turtle, Screen
import random
RADIUS = 10
def getColor(turtle):
choice = turtle.pencolor()
while choice == turtle.pencolor():
choice = random.choice(["red", "green", "blue"])
return choice
def drawFace(turtle, x, y):
turtle.pencolor(getColor(turtle))
turtle.penup()
turtle.goto(x, y - RADIUS)
turtle.pendown()
turtle.circle(RADIUS)
tess = Turtle()
drawFace(tess, 5, 0)
drawFace(tess, 15, 0)
screen = Screen()
screen.exitonclick()
Related
Screenshot of output image
I made a random walk program using turtle and I want it show where the two turtles cross paths by changing the color.
`import turtle as T
import random as R
t = T.Turtle()
u = T.Turtle()
t.speed(0)
u.speed(0)
t.hideturtle()
u.hideturtle()
t.color("red")
u.color("blue")
def randWalk(num):
for i in range(0, num):
x = R.choice((-1,1))
X = R.choice((-1,1))
y = R.choice((-1,1))
Y = R.choice((-1,1))
t.forward(x)
u.forward(X)
if y == 1:
t.left(90)
t.forward(1)
else:
t.right(90)
t.forward(1)
if Y == 1:
u.left(90)
u.forward(1)
else:
u.right(90)
u.forward(1)
randWalk(4000)`
Turtle can't interrogate what color is currently on the screen, so one way to approach this might be to have some sort of backing store where you keep track of what color was written to what pixel. Here's a rough example using Python lists:
from turtle import Screen, Turtle
from random import choice
WIDTH, HEIGHT = 300, 300
PEN_COLORS = ['red', 'blue']
OVERLAP_COLOR = 'green'
def randWalk(number):
for _ in range(number):
for turtle in turtles:
direction = choice((-1, 1))
turtle.forward(direction)
x, y = map(round, turtle.position())
old_color = color = turtle.pencolor()
turtle.undo() # undo forward()
if grid[y][x] and grid[y][x] != color:
color = OVERLAP_COLOR
turtle.pencolor(color)
turtle.goto(x, y) # redo forward()
turtle.pencolor(old_color)
grid[y][x] = color
choice((turtle.left, turtle.right))(90)
screen.update()
screen = Screen()
screen.setup(WIDTH, HEIGHT)
screen.tracer(False)
grid = [[None] * WIDTH for _ in range(HEIGHT)]
turtles = []
for color in PEN_COLORS:
turtle = Turtle()
turtle.hideturtle()
turtle.pencolor(color)
turtles.append(turtle)
randWalk(4000)
screen.tracer(True)
screen.exitonclick()
There is additional complication in the code as turtle walks a floating point plane but we need to coerce it to an integer plane to accommodate our backing store and reduce undesirable drawing artifacts.
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
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()
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()
I'm new to turtle graphics in Python, and I'm running into some issues with a particular problem. I'm trying to generate a star that uses a while loop to draw random jagged lines from the center of a circle.
Each line should have a distance of 250. I'm using the penup pendown and setpos commands within the loop to draw these random lines, and each line should be a random color.
Here's an idea of what I'm hoping to generate: random star
Here's the code I have so far:
# tg_random_star.py
from random import randrange
from turtle import *
MAX_ANGLE = 30
def jaggedLine(turtle, pieces, pieceLength):
for i in range(pieces):
turtle.forward(pieceLength)
r = randrange(-MAX_ANGLE, MAX_ANGLE + 1)
turtle.right(r)
def jumpToCenter(turtle):
turtle.penup()
turtle.setpos(0, 0)
turtle.pendown()
def randomColor(turtle):
turtle.colormode(255)
r = randrange(255) # red component of color
g = randrange(255) # green component
b = randrange(255) # blue component
turtle.pencolor(r, g, b)
def main():
colormode(255)
t = Turtle()
jaggedLine(t, 10, 30)
jumpToCenter(t)
jaggedLine(t, 10, 30)
if __name__ == "__main__":
main()
It currently generates 2 lines, but the turtle.pencolor(r, g, b) and the colormode(255) don't seem to be working, as both lines are black. Any idea why these lines aren't in color?
Rather than using for i in range(pieces) to draw lines that are based on the number of segments, how can I use a while loop to draw jagged lines that each have a distance of 250? In other words, I want each line to have a distance of 250 before drawing a new line from the center.
(Maybe I could use the xcor and ycor methods to find the turtle’s position, then calculate the distance using the distance formula?)
def distance(p0, p1):
return math.sqrt((p0[0] - p1[0])**2 + (p0[1] - p1[1])**2)`
Any help or explanation would be appreciated, thank you.
Any idea why these lines aren't in color?
That one's easy, it's because you never actually call randomColor()
Rather than using for i in range(pieces) to draw lines that are based
on the number of segments, how can I use a while loop to draw jagged
lines that each have a distance of 250?
Here we can take advantage of the under utilized .distance() method of turtle to tell us how far we are from center. This is straight line distance, not path travelled distance, which seems to match your target illustration:
from turtle import Turtle, Screen
from random import randrange
MAX_ANGLE = 30
MAX_DISTANCE = 250
def jaggedLine(t, pieceLength):
randomColor(t)
while t.distance(0, 0) < MAX_DISTANCE:
angle = randrange(-MAX_ANGLE, MAX_ANGLE + 1)
t.right(angle)
t.forward(pieceLength)
def jumpToCenter(t):
t.penup()
t.home() # return turtle to original position
t.pendown()
def randomColor(t):
# red, green & blue components of turtle color
r, g, b = randrange(255), randrange(255), randrange(255)
t.pencolor(r, g, b)
def main():
screen = Screen()
screen.tracer(False) # because I have no patience
screen.colormode(255)
turtle = Turtle()
turtle.hideturtle()
turtle.pensize(2)
for angle in range(0, 360, 2):
jumpToCenter(turtle)
turtle.setheading(angle)
jaggedLine(turtle, 30)
screen.tracer(True) # forces an update
screen.mainloop()
if __name__ == "__main__":
main()
OUTPUT
I am trying to make a program in Turtle that draws a Christmas Tree and then some baubles, which I want to be placed randomly on the tree. However because a Christmas Tree is an irregular shape I am not able to place the baubles by randomly choosing x and y co-ordinates. Is there a way to randomly place the baubles on the tree?
I was considering an "turtle.pendown()" and then "if turtle.pen touching "green"" but I am not sure how to code this.
Any help would be greatly appreciated.
One simple, graphic, approach is to:
Find a Python module that has a routine for performing the "point
in polygon"
inclusion
test
Use turtle's begin_poly(), end_poly(), and get_poly() to capture the
vertices that your code generates when drawing the tree
Randomly generate ornaments within the bounding box of the tree but
also apply the crossing number test to see if their centers are on
the tree
Here's an example implementation using an (exceptionally) abstract tree and ornaments:
from turtle import Turtle, Screen
from random import randrange, choice
from point_in_polygon import cn_PnPoly
screen = Screen()
WINDOW_WIDTH, WINDOW_HEIGHT = screen.window_width(), screen.window_height()
COLORS = ["red", "yellow", "gold", "blue", "white", "pink"]
def draw_abstract_tree(turtle):
width = WINDOW_WIDTH//4
turtle.penup()
turtle.goto(0, -WINDOW_HEIGHT//4)
turtle.pendown()
for _ in range(8):
turtle.forward(width)
turtle.left(150)
turtle.forward(1.156 * width)
turtle.right(150)
width *= 0.9
turtle.left(210)
for _ in range(8):
turtle.forward(1.156 * width)
turtle.left(150)
turtle.forward(width)
turtle.right(150)
width /= 0.9
turtle.goto(0, -WINDOW_HEIGHT//4)
turtle.setheading(0)
def decorate_tree(turtle, polygon):
turtle.penup()
for _ in range(1000):
x = randrange(-WINDOW_WIDTH/4, WINDOW_WIDTH/4)
y = randrange(-WINDOW_HEIGHT/4, WINDOW_HEIGHT)
diameter = randrange(1, 12)
if cn_PnPoly((x, y), polygon):
turtle.goto(x, y)
turtle.color(choice(COLORS))
turtle.dot(diameter)
yertle = Turtle(visible=False)
yertle.speed("fastest")
yertle.color("darkgreen")
yertle.begin_poly()
draw_abstract_tree(yertle)
yertle.end_poly()
polygon = yertle.get_poly()
yertle.begin_fill()
draw_abstract_tree(yertle)
yertle.end_fill()
decorate_tree(yertle, polygon)
screen.exitonclick()
OUTPUT
I think turtle doesn't have method to check color.
But turtle uses Canvas from tkinter which have function find_overlaping(rectangle) to check if some objects overlaps this rectangle. Maybe it could works. Maybe you could check if there is tree in some small rectange in random place.
turtle.getcanvas()
tkinter: Canvas.find_overlapping()
I am trying to create somewhat of a color wheel using the turtle module in Python. Let's say I have a list of colors:
colors = ["#880000","#884400","#888800","#008800","#008888","#000088",
"#440088","#880088"]
I am aiming to go around a circle with a radius of 250px plotting in the colors:
def drawColors():
for color in colors:
turtle.color(dark)
for i in range(len(colors)):
turtle.begin_fill
turtle.circle(150)
turtle.end_fill()
turtle.done()
You can do it by dividing the circle up into multiple circular sectors (aka pie slices) and drawing each one in a different color. The tricky part doing it with turtle graphics is setting the initial position and heading (or direction) of the turtle to be at the start of the arc of each one. Also, unlike with the case with a full circle, you need to manually close the figure before filling it by drawing the final line segment from the end of the arc back to the center of the circle.
While this could be calculated mathematically, doing that is avoided in the following code by remembering, for all but the first sector, where the previous one left off and using that as the starting position and heading for the next. Fortunately for the initial one, these values are relatively simple to compute: the position is set to the (circle_center x value + radius, circle_center y value) with a due North heading of 90°.
import turtle
colors = ['#880000','#884400','#888800','#008800',
'#008888','#000088','#440088','#880088']
def draw_color_wheel(colors, radius, center=(0, 0)):
slice_angle = 360 / len(colors)
heading, position = 90, (center[0] + radius, center[1])
for color in colors:
turtle.color(color, color)
turtle.penup()
turtle.goto(position)
turtle.setheading(heading)
turtle.pendown()
turtle.begin_fill()
turtle.circle(radius, extent=slice_angle)
heading, position = turtle.heading(), turtle.position()
turtle.penup()
turtle.goto(center)
turtle.end_fill()
draw_color_wheel(colors, 150, center=(25, 50))
turtle.hideturtle()
print('done - press any key to exit')
turtle.onkeypress(exit)
turtle.listen()
turtle.done()
Result
Since this question has become active again, let's solve it using stamping rather than drawing:
from turtle import Turtle, Screen
colors = ['#880000', '#884400', '#888800', '#008800',
'#008888', '#000088', '#440088', '#880088']
def draw_color_wheel(colors, radius, center=(0, 0)):
slice_angle = 360 / len(colors)
yertle = Turtle(visible=False)
yertle.penup()
yertle.begin_poly()
yertle.sety(radius)
yertle.circle(-radius, extent=slice_angle)
yertle.home()
yertle.end_poly()
screen.register_shape('slice', yertle.get_poly())
yertle.shape('slice')
yertle.setposition(center)
for color in colors:
yertle.color(color)
yertle.stamp()
yertle.left(slice_angle)
screen = Screen()
draw_color_wheel(colors, 250, center=(25, 50))
screen.exitonclick()
OUTPUT
This approach takes slightly less code and produces noticeably faster output.