This my program using turtle to draw the circle target:
import turtle
def origin_circle(turtle, radius):
turtle.penup()
turtle.goto(0, -radius)
turtle.pendown()
turtle.circle(radius)
for radius in range(100, 200, 10):
origin_circle(turtle, radius)
The code makes a moving curve, but I want the circle to be drawn at once.
The circle() method draws a circle, but the dot() method stamps one out. However, the dot() method doesn't have a separate line and fill concept and tends to overwrite itself, so we have to handle it carefully:
import turtle
def origin_circle(turtle, radius):
turtle.dot(radius + 2, 'black')
turtle.dot(radius, 'white')
for radius in range(200, 0, -40):
origin_circle(turtle, radius)
turtle.hideturtle()
turtle.mainloop()
Alternatively, we could stamp out circular cursors ourselves:
import turtle
def origin_circle(turtle, radius):
turtle.shapesize(radius)
turtle.stamp()
turtle.shape('circle')
turtle.color('black', 'white')
for radius in range(10, 0, -2):
origin_circle(turtle, radius)
turtle.hideturtle()
turtle.mainloop()
But this doesn't produce as pleasing a result:
Of course, we can always cheat and use turtle.speed('fastest'), or better yet, turn tracing off altogether:
import turtle
def origin_circle(turtle, radius):
turtle.penup()
turtle.sety(-radius)
turtle.pendown()
turtle.circle(radius, steps=90)
turtle.tracer(False)
for radius in range(20, 120, 20):
origin_circle(turtle, radius)
turtle.hideturtle()
turtle.tracer(True)
turtle.mainloop()
But the result still won't look as nice as the turtle.dot() approach, even if you bump up the steps parameter of turtle.circle():
for the first code how to add an arrow on the top of each curve, one
at down of each curve?
This is easier done modifying my third example as we can more easily draw semicircles and stamp the cursor. I'm using a custom cursor for arrow alignment across circles purposes:
import turtle
def origin_circle(turtle, radius):
turtle.penup()
turtle.sety(-radius)
turtle.pendown()
turtle.stamp()
turtle.circle(radius, extent=180, steps=45)
turtle.stamp()
turtle.circle(radius, extent=180, steps=45)
turtle.addshape("pointer", ((0, 0), (5, -4), (0, 4), (-5, -4)))
turtle.shape("pointer")
turtle.tracer(False)
for idx, radius in enumerate(range(20, 120, 20), start=0):
origin_circle(turtle, radius)
turtle.hideturtle()
turtle.tracer(True)
turtle.mainloop()
import turtle
ab=turtle.Turtle()
ab.speed(0)
import turtle
def zielscheibe(ringe=10):
if ringe<1 or ringe>1000:
ab.write('Bitte eine Zahl zwischen 1 und 1000 eingeben')
return
ab.pu()
ab.goto(300,0)
ab.seth(90)
x=300/ringe
for n in range(ringe):
ab.pd()
if n ==ringe-1:
ab.color('black')
elif n %2==0:
ab.color('red')
else:
ab.color('white')
ab.begin_fill()
ab.circle(300-x*n)
ab.end_fill()
ab.pu()
ab.left(90)
ab.fd(x)
ab.right(90)
zielscheibe(10)
turtle.mainloop()
Related
I'm trying to stamp the same shape (image I'm adding to turtle) in multiple positions on my canvas. But, it seems like every time I stamp the second shape, the first one disappears.
Is there a way to display multiple stamps on a canvas using the same shape/image? This doesn't seem to be a problem when using shapes already in turtle.
You should be able to stamp any number of copies of the same image without them disappearing until you request them to do so. For a custom polygon shape:
from turtle import Screen, Shape, Turtle
POLYGON = (
(10, 10),
(0, 10),
(-10, 0),
(0, -10),
(10, -10),
)
screen = Screen()
screen.register_shape('house', Shape('polygon', POLYGON))
turtle = Turtle('house')
turtle.penup()
for x in range(-200, 200, 30):
turtle.setx(x)
turtle.stamp()
turtle.hideturtle()
screen.exitonclick()
Or for a custom image shape:
from turtle import Screen, Turtle
IMAGE = "home-5-24.gif" # https://www.iconsdb.com/gray-icons/home-5-icon.html
screen = Screen()
screen.register_shape(IMAGE)
turtle = Turtle(IMAGE)
turtle.penup()
for x in range(-200, 200, 30):
turtle.setx(x)
turtle.stamp()
turtle.hideturtle()
screen.exitonclick()
I am having problems trying to draw (in python using turtle) the archery target and asking the user for input for location of the target and diameter of the yellow center. target image
Code I have so far (probably wrong):
import turtle
turtle = turtle.Turtle()
def origin_circle(turtle, radius):
turtle.dot(100, 'black')
turtle.dot(75, 'cyan')
turtle.dot(50, 'red')
turtle.dot(25, 'yellow')
for radius in range(100, 200, 10):
origin_circle(turtle, radius)
turtle.hideturtle()
So... nobody is able to answer my question?
It's not a difficult problem -- you even have a loop you don't need:
from turtle import Screen, Turtle
def origin_circle(turtle, diameter):
turtle.dot(diameter * 4, 'black')
turtle.dot(diameter * 3, 'cyan')
turtle.dot(diameter * 2, 'red')
turtle.dot(diameter, 'yellow')
diameter = float(input("Diameter of target center: "))
x_coordinate = float(input("X coordinate of target center: "))
y_coordinate = float(input("Y coordinate of target center: "))
screen = Screen()
turtle = Turtle()
turtle.hideturtle()
turtle.penup()
turtle.goto(x_coordinate, y_coordinate)
origin_circle(turtle, diameter)
screen.exitonclick()
Note that turtle.dot() takes a diameter as input and draws when the pen is up or down but turtle.circle() uses a radius and only draws when the pen is down.
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 am writing this code to print polygons. If the number is two or less, it is supposed to print nothing according to my professor but I cant figure this out. Can somebody tell me what I need to write in my function for 2 or less side numbers to not print anything?
import turtle
import math
turtle.shape("turtle")
turtle.speed(3)
from turtle import *
pensize (5)
pencolor ("purple")
def polygon(num_side, length):
for i in range(num_side):
turtle.forward(length)
turtle.left(360/num_side)
print(polygon(2, 100)) #nothing?
turtle.penup()
turtle.goto(50, 0)
turtle.pendown()
print(polygon(3,100)) #triangle
turtle.penup()
turtle.goto(50, 0)
turtle.pendown()
print(polygon(4, 100)) #square
turtle.penup()
turtle.goto(50, 0)
turtle.pendown()
print(polygon(5, 100)) #pentagon
turtle.penup()
turtle.goto(50, 0)
turtle.pendown()
print(polygon(6, 100)) #hexagon
turtle.penup()
turtle.goto(50, 0)
turtle.pendown()
print(polygon(7, 100)) #heptagon
You need to exit if the number of sides is less than three and only output if n is more than 2. Thus, the if will take care of this.
import turtle
import math
turtle.shape("turtle")
turtle.speed(3)
turtle.pensize (5)
turtle.pencolor ("purple")
def polygon(num_side, length):
if num_side > 2:
for i in range(num_side):
turtle.forward(length)
turtle.left(360/num_side)
turtle.pendown()
for n in range(10):
polygon(n, 100)
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.