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()
Related
How do I fill in this shape I drew?
Here's the code:
t = turtle.Turtle()
t2 = t.clone()
#the shapes do not go beyond the screen
for count in range(2):
t.circle(100, 180)
t.right(180)
t2.circle(200, 180)
set t.color(turtle.bgcolor())
start begin_fill on first t2 and then t
draw
end_fill t2 first
and then end_fill t
Entire code:
>>> import turtle
>>> t = turtle.Turtle(); t2 = t.clone()
>>> t.color(turtle.bgcolor())
>>> t2.begin_fill(); t.begin_fill()
>>> t2.circle(200, 180)
>>> for count in range(2):
t.circle(100, 180)
t.right(180)
>>> t2.end_fill(); t.end_fill()
My inclination would be to draw the shape with a single turtle to simplify the problem:
import turtle
turtle.begin_fill()
turtle.circle(100, 180)
turtle.circle(200, -180)
turtle.circle(100, 180)
turtle.end_fill()
turtle.hideturtle()
turtle.done()
The approach of #Superior is perfectly valid (+1), but I'd code it differently:
from turtle import Screen, Turtle
screen = Screen()
t1 = Turtle()
t1.begin_fill()
t1.circle(200, 180)
t1.end_fill()
t2 = Turtle()
t2.color(screen.bgcolor())
t2.begin_fill()
for _ in range(2):
t2.circle(100, 180)
t2.right(180)
t2.end_fill()
screen.exitonclick()
The above can also be done just as easy with a single turtle. And finally, for completeness, we could draw this figure via stamping, which we can do with one or more turtles:
from turtle import Screen, Turtle
screen = Screen()
t1 = Turtle()
t1.hideturtle()
t1.shape('circle')
t1.penup()
t1.shapesize(20)
t1.stamp()
t1.color(screen.bgcolor())
t1.shapesize(stretch_len=10)
t2 = t1.clone()
t2.shapesize(stretch_wid=10)
for sign in (-1, 1):
t2.sety(sign * 100)
t2.stamp()
t1.shape('square')
t1.backward(100)
t1.stamp()
screen.exitonclick()
Generally, I wouldn't clone() turtles unless there's some feature set on the original turtle that you want to preserve in the clone. In your code, you clone a brand new turtle which has no benefit over creating a new turtle instance. In the stamping example above, cloning is used to preserve the color and stretch-width of the original turtle before the original turtle itself changes.
Is it possible to make the get_poly function to leave the shape unfilled.
For example, in this code can the red shapes with the blue fill be not filled with any color (white fill is not what i am looking for):
from turtle import Turtle, Screen, Shape
screen = Screen()
turtle = Turtle(visible=False)
turtle.speed("fastest")
turtle.penup()
shape = Shape("compound")
for octogon in range(8):
turtle.begin_poly()
for _ in range(8):
turtle.left(45)
turtle.fd(20)
turtle.end_poly()
shape.addcomponent(turtle.get_poly(), "blue", "red")
turtle.right(45)
turtle.fd(60)
screen.register_shape("octogons", shape)
octopus = Turtle(shape="octogons")
octopus.penup()
octopus.speed("slowest")
octopus.goto(300, 200)
octopus.goto(-200, 200)
screen.exitonclick()
Try this:
shape.addcomponent(turtle.get_poly(), "", "red")
I have a couple of questions. Firstly, I am wondering how to I get shape sizes for shapes I call to be dynamic, and adjust based on my movement of the window that they are in. Is there a simple command for this? Secondly, I am wondering if instead of using something like Turtle to draw images, how do I get an image to just appear once I run drawing code, as opposed to watching it be drawn?
from turtle import *
import math
radius = 100
t = turtle.Turtle()
radius = 100
colormode(255)
t.speed(1)
t.color(0,255,0)
fillcolor(200, 125, 200)
t.begin_fill()
t.circle(radius)
t.end_fill()
exitonclick()
One way you can go about this is by designing a turtle cursor and stamping it. Cursors are drawn all at once and have more graphics operations at their disposal, like resizing, shear, etc. Here's a simple example using turtle's built in circle shape but you can just as easily design your own and register it as a cursor:
RADIUS = 100
CURSOR_SIZE = 20
screen = Screen()
screen.colormode(255)
turtle = Turtle("circle", visible=False)
turtle.speed('fastest')
turtle.penup()
turtle.pencolor(0, 255, 0)
turtle.fillcolor(200, 125, 200)
turtle.shapesize(RADIUS / CURSOR_SIZE, outline=5)
turtle.stamp()
turtle.goto(250, 250)
turtle.shapesize(2 * RADIUS / CURSOR_SIZE, outline=10)
turtle.stamp()
screen.exitonclick()
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()
I have added the image with the relevant code. My challenge is setting a desired position of the image. The default position is the center of the canvas, how do I change that, please help.
Thank you
Assuming you've loaded some *.gif image as the turtle's image, you can then turtle.goto() (or turtle.setposition(), etc.) where ever you want on the canvas and turtle.stamp() the image to leave it behind:
from turtle import Turtle, Screen
# https://cdn-img.easyicon.net/png/10757/1075705.gif
SQUIRREL_IMAGE = '1075705.gif'
screen = Screen()
screen.register_shape(SQUIRREL_IMAGE)
turtle = Turtle(shape=SQUIRREL_IMAGE)
turtle.penup()
turtle.goto(100, 100)
turtle.stamp()
turtle.goto(-100, -100)
turtle.stamp()
turtle.hideturtle()
screen.exitonclick()
OUTPUT