I need some help. I want to center the hexagon into the larger hexagon but I don't now how to do it. Below I have the source code and an image link to the output.
import turtle
polygon = turtle.Turtle()
num_sides = 6
side_length = 20
move_left = 60
polygon.pensize(2)
polygon.pencolor((245, 176, 66))
for turtle_move in range(num_sides):
polygon.forward(side_length)
polygon.left(move_left)
polygon.penup()
polygon.left(2)
polygon.pendown()
side_length2 = 40
move_left2 = 60
I want to center the hexagon inside the larger hexagons, but I don't know what to do.
for turtle_move in range(num_sides):
polygon.forward(side_length2)
polygon.left(move_left2)
Here is the output:
There are any number of ways to do this if you read about the geometry of hexagons, eg. on Wikipedia:
from turtle import Screen, Turtle
NUM_SIDES = 6
SIDE_LENGTH = 20
ANGLE_LEFT = 60
screen = Screen()
turtle = Turtle()
for _ in range(NUM_SIDES):
turtle.forward(SIDE_LENGTH)
turtle.left(ANGLE_LEFT)
turtle.penup()
turtle.backward(SIDE_LENGTH / 2)
turtle.sety(-SIDE_LENGTH * 3**0.5/2)
turtle.pendown()
for _ in range(NUM_SIDES):
turtle.forward(SIDE_LENGTH*2)
turtle.left(ANGLE_LEFT)
turtle.hideturtle()
screen.exitonclick()
One alternate approach is to use the turtle circle() method to draw the hexagons, then it becomes a matter of centering two circles:
from turtle import Screen, Turtle
NUM_SIDES = 6
SIDE_LENGTH = 20
circumradius = SIDE_LENGTH
screen = Screen()
turtle = Turtle()
for _ in range(2):
turtle.penup()
turtle.sety(-circumradius)
turtle.pendown()
turtle.circle(circumradius, steps=NUM_SIDES)
circumradius *= 2
turtle.hideturtle()
screen.exitonclick()
I'm assuming by your use of pencolor((245, 176, 66)) you're using a site like Repl.it or some other non-standard Python turtle implementation, so you may need to adjust the examples above slightly to suit your environment.
Related
Something similar to the picture attached. I tried modifying the code I got online. But my code goes to infinity loop
[1]: https://i.stack.imgur.com/HfKog.png
def draw_circle(radius):
turtle.up()
turtle.goto(0, radius) # go to (0, radius)
turtle.pendown() # pen down
times_y_crossed = 0
x_sign = 1.0
while times_y_crossed <= 1:
turtle.dot(5, "Red")
turtle.forward(5) # move by 1/360
turtle.right(1.0)
turtle.penup()
turtle.forward(5) # move by 1/360
turtle.right(1.0)
x_sign_new = math.copysign(1, turtle.xcor())
if x_sign_new != x_sign:
times_y_crossed += 10
x_sign = x_sign_new
turtle.up() # pen up
return
There are some issues with your code, like it does not count with the radius and the color for the pen was not set and as I've checked it did a half circle for me.
I show you a simple working example, first a dashed version because your original code looks like you wanted a dashed circle
import turtle
import math
def draw_circle_dashed(radius):
turtle.up()
turtle.goto(0, radius) # go to (0, radius)
times_y_crossed = 0
dist=2*math.pi*radius/360
turtle.pencolor("red")
for _ in range(180):
turtle.pendown()
turtle.forward(dist) # move by 1/360
turtle.right(1.0)
turtle.penup()
turtle.forward(dist) # move by 1/360
turtle.right(1.0)
turtle.up() # pen up
return
draw_circle_dashed(200)
and a dotted variant as well because of the question title
import turtle
import math
def draw_circle_dotted(radius):
turtle.up()
turtle.goto(0, radius) # go to (0, radius)
dist=2*math.pi*radius/360
for _ in range(360):
turtle.dot(2,"red")
turtle.forward(dist) # move by 1/360
turtle.right(1.0)
turtle.up() # pen up
return
draw_circle_dotted(300)
We can use turtle's own circle() method to do this as we can arbitrarily start and stop it, leaving behind dots as we do:
from turtle import Screen, Turtle
from math import pi
DOT_DIAMETER = 5
def draw_circle(radius):
turtle.penup()
circumference = 2 * pi * radius
dot_extent = 360 * DOT_DIAMETER*2 / circumference # diameter to angle
extent = 0
while extent < 360:
turtle.dot(DOT_DIAMETER)
turtle.circle(radius, extent=dot_extent)
extent += dot_extent
screen = Screen()
turtle = Turtle()
turtle.color('red')
draw_circle(100)
turtle.hideturtle()
screen.exitonclick()
Using what we learned from that exercise, let's now fix your code. The issue I see is this:
turtle.right(1.0)
The angle to turn is dependent on the dot diameter, but we actually have to calculate it:
from turtle import Screen, Turtle
from math import pi, copysign
DOT_DIAMETER = 5
def draw_circle(radius):
turtle.penup()
turtle.sety(radius)
diameter = 2 * radius
circumference = pi * diameter
dot_extent = 360 * DOT_DIAMETER / circumference # diameter to angle
times_y_crossed = 0
x_sign = 1
while times_y_crossed < 2:
turtle.dot(DOT_DIAMETER, 'red') # draw the dot
turtle.right(dot_extent)
turtle.forward(DOT_DIAMETER)
turtle.right(dot_extent) # draw the gap
turtle.forward(DOT_DIAMETER)
x_sign_new = copysign(1, turtle.xcor())
if x_sign_new != x_sign:
times_y_crossed += 1
x_sign = x_sign_new
turtle.pendown()
screen = Screen()
turtle = Turtle()
turtle.color('red')
draw_circle(100)
turtle.hideturtle()
screen.exitonclick()
By not calculating the angle, and using a fixed angle of 1.0, you were off by a factor of two.
I am trying to draw a checker board using the Turtle library and am running into an error where the board window does not open. It was working at the beginning of my session about 30 minutes ago but, I changed some stuff and want to know why it changed.
Here is my code:
##This program draws a checkboard using the turtle library
import turtle
#below initiates the turtle pen and screen
penMain = turtle.Turtle()
turtleMain = turtle.Screen()
def turtleBoard():
for x in range(4):
penMain.forward(30)
penMain.left(90)
penMain.forward(30)
turtleMain.setup(600, 600)
penMain.speed(50)
for a in range(8):
penMain.up()
penMain.setpos(0, 30 * a)
penMain.down()
for x in range(8):
if (a + x)% 2 == 0:
squareColor = 'black'
else:
squareColor = 'white'
penMain.fillcolor(squareColor)
penMain.begin_fill()
turtleBoard()
penMain.end_fill()
I believe this code works besides my one error! Thank you all for your help in advance!
I can't say what changes you made to get your current code, but this code seems to be working:
##This program draws a checkboard using the turtle library
import turtle
#below initiates the turtle pen and screen
penMain = turtle.Turtle()
turtleMain = turtle.Screen()
def turtleBoard():
penMain.forward(30)
turtleMain.setup(600, 600)
penMain.speed(50)
for a in range(8):
for x in range(8):
penMain.up()
penMain.setpos(30 * x, 30 * a)
penMain.down()
penMain.begin_fill()
for xx in range(4):
penMain.forward(30)
penMain.left(90)
if a%2 == x%2:
squareColor = 'black'
else:
squareColor = 'white'
penMain.fillcolor(squareColor)
penMain.end_fill()
turtleBoard()
turtle.done()
Now that we've seen that your code can be made to work, let's consider stamping instead of drawing to make it work more simply and more quickly:
from turtle import Screen, Turtle
SQUARES_PER_EDGE = 8
SQUARE_SIZE = 30 # in pixels
OFFSET = SQUARE_SIZE * (SQUARES_PER_EDGE / 2) - SQUARE_SIZE/2 # center the board
CURSOR_SIZE = 20
def turtleBoard():
turtle.shape('square')
turtle.shapesize(SQUARE_SIZE / CURSOR_SIZE)
turtle.penup()
for y in range(SQUARES_PER_EDGE):
for x in range(SQUARES_PER_EDGE):
turtle.goto(x * SQUARE_SIZE - OFFSET, y * SQUARE_SIZE - OFFSET)
turtle.fillcolor('black' if y % 2 == x % 2 else 'white')
turtle.stamp()
screen = Screen()
screen.setup(600, 600)
turtle = Turtle()
turtle.speed('fastest') # because I have no patience
turtleBoard()
screen.exitonclick()
I lined up the indent of the bottom 4 lines with the last 'else' statement and it worked. Thank you guys!
I'm trying to draw on a small 200x200 screen using turtle, however the drawing doesn't pop up as full size, it opens a smaller window and I have to scroll up/down, left/right (just a bit) to see the whole drawing. I don't have this problem with larger windows. How do I prevent this?
import turtle
import random
height, width = 200, 200
screen = turtle.Screen()
screen.setup(width, height)
screen.setworldcoordinates(0, 0, width, height)
t = turtle.Turtle()
t.speed(1)
for _ in range(5):
t.penup()
t.goto(random.randint(20, width-20), random.randint(0, height-40))
t.pendown()
t.circle(20)
edit: screenshot, I want the actual size window instead of the scrolls
You could resize the window to 420×420.
If you don't want to resize your window, I suggest modifying the values for the keys "canvwidth" and "canvheight" keys in the turtle._CFG dictionary:
import turtle
import random
height, width = 200, 200
screen = turtle.Screen()
screen.setup(width, height)
screen.setworldcoordinates(0, 0, width, height)
turtle._CFG.update({"canvwidth": width-20, "canvheight": height-20}) # Removing the scroll bars
t = turtle.Turtle()
t.speed(1)
for _ in range(5):
t.penup()
t.goto(random.randint(20, width-20), random.randint(0, height-40))
t.pendown()
t.circle(20)
screen.exitonclick()
Using small windows in turtle is a can of worms. If #TheOneMusic's simple solution (+1) is good enough for your purposes, go for it! On my system, your setworldcoordinates() call gets rid of the scroll bars, so I don't even see the issue. So, another approximate solution might be to upgrade to current Python and tkinter.
However, neither is an exact solution. If we add code to draw a 200 x 200 box around our drawing area:
t.penup()
t.color('red')
t.goto(0, 0) # because of setworldcoordinates()
t.pendown()
for _ in range(4):
t.forward(200)
t.left(90)
We get the box skewed:
To solve this problem more precisely, involves uglier code:
from turtle import Screen, Turtle
from random import randint
TRUE_WIDTH, TRUE_HEIGHT = 200, 200
CURSOR_SIZE = 20 # for drawing frame around edge
RADIUS = 20
CHROME = 14 # magic number possibly derivable from tkinter
width, height = TRUE_WIDTH + CHROME, TRUE_HEIGHT + CHROME # needs to be slightly larger than 200 target
offset_x = CHROME / -2 + 2
offset_y = CHROME / 2 - 2
screen = Screen()
screen.setup(width, height)
screen.screensize(width/2, height/2) # backing store needs to be smaller than window
screen.setworldcoordinates(0, 0, TRUE_WIDTH, TRUE_HEIGHT)
# Draw red frame around edge to "prove" drawing area
frame = Turtle(shape='square', visible=False)
frame.shapesize(TRUE_HEIGHT / CURSOR_SIZE, TRUE_WIDTH / CURSOR_SIZE) # 200 x 200 frame
frame.color('red', 'white')
frame.penup()
frame.goto(TRUE_WIDTH/2 + offset_x, TRUE_HEIGHT/2 + offset_y)
frame.stamp()
turtle = Turtle()
turtle.speed('fastest') # because I have no patience
for _ in range(5):
turtle.penup()
turtle.goto(randint(RADIUS, TRUE_WIDTH - RADIUS) + offset_x, randint(0, TRUE_HEIGHT - RADIUS*2) + offset_y)
turtle.pendown()
turtle.circle(RADIUS)
screen.exitonclick()
But this sort of detail work could easily be undone by a future release of turtle and/or tkinter. If you can live with turtle's default window, life gets easier.
When going through the book "How to think like...", I got stuck with exercise 4.9.2.
The question is: "Write a program to draw this. Assume the innermost square is 20 units per side, and each successive square is 20 units bigger, per side, than the one inside it"
The following code represents how far I got till now:
import turtle
wn = turtle.Screen()
wn.bgcolor("lightgreen")
tess = turtle.Turtle()
def draw_square(t,size):
for i in range(4):
tess.forward(size)
tess.left(90)
size = 20
for j in range(3):
tess.pensize(3)
draw_square(tess,size)
size = size + 20
tess.penup()
tess.goto(-20, -20)
tess.pendown()
wn.mainloop()
Can someone be so kind and show me the right direction please?
Thanks!
Swen
The problem is here:
tess.goto(-20, -20)
You have two issues. First, if each square is 20 units bigger and you offset each square by (-20, -20) all squares would share one corner. Instead you want to offset the corner of the square by (-10, -10) so that the inner square is offset by 10 units on all sides.
The second issue is that .goto(x, y) sets an absolute position, not an offset. To move to an offset you need to calculate a new absolute position based on the offset:
tess.goto(tess.xcor()-10, tess.ycor()-10)
Or
tess.goto(tess.pos() + (-10, -10))
Sometimes when you're stuck, a good approach with turtle graphics is to think outside the square. If we consider the desired result as badly drawn concentric circles then the problem reduces to:
from turtle import Turtle, Screen
HYPOTENUSE = (2 ** 0.5) / 2
screen = Screen()
screen.bgcolor("lightgreen")
tess = Turtle()
tess.pencolor("red")
tess.setheading(45)
tess.width(3)
for radius in range(20, 20 * 5 + 1, 20):
tess.penup()
tess.goto(radius/2, -radius/2)
tess.pendown()
tess.circle(radius * HYPOTENUSE, steps=4)
screen.exitonclick()
OUTPUT
import turtle
def drawSquare (t, size):
for i in range (4):
t.forward(size)
t.left(90)
def main():
wn = turtle.Screen()
wn.bgcolor('black')
pat = turtle.Turtle()
pat.pensize(2)
pat.speed(10)
pat.color('blue')
space = -10
for i in range(20, 105, 20):
drawSquare(pat,i)
pat.up()
pat.goto(space, space)
pat.down()
space = space - 10
wn.exitonclick()
main()
import turtle
def draw_sqr(name,size):
for i in range(4):
name.forward(size)
name.left(90)
name.penup()
name.backward(10)
name.right(90)
name.forward(10)
name.left(90)
name.pendown()
window = turtle.Screen()
window.bgcolor('lightgreen')
window.title("conc_sqr")
x = turtle.Turtle()
x.color('hotpink')
x.pensize(3)
for i in range(5):
draw_sqr(x,20 + 20*i)
window.mainloop()
def draw_rectangle(animal, width, height):
for _ in range(2):
animal.forward(width)
animal.left(90)
animal.forward(height)
animal.left(90)
def draw_square(animal, size):
draw_rectangle(animal, size, size)
def make_window(back_color,title):
window = turtle.Screen()
window.bgcolor(back_color)
window.title(title)
return window
def make_turtle(color, size):
animal = turtle.Turtle()
animal.color(color)
animal.pensize(size)
return animal
import turtle
window = make_window("lightgreen","Squares")
tess = make_turtle("hotpink",3)
size_sqr=20
adjustment = 10
for _ in range(5):
draw_square(tess,size_sqr)
size_sqr += 20
tess.penup()
tess.backward(20/2)
tess.right(90)
tess.forward(20/2)
tess.left(90)
tess.pendown()
import turtle
def drawsquare(t,sz): #(turtle, size)
for i in range(4):
t.fd(sz)
t.right(90)
def main():
wn = turtle.Screen()
your_turtle = turtle.Turtle()
your_turtle.pensize(3)
wn.bgcolor("light green")
your_turtle.pencolor("hot pink")
for i in range(1,6):
drawsquare(your_turtle,20*i)
your_turtle.up()
your_turtle.left(135)
your_turtle.fd(14.142) #the distance between each square
your_turtle.right(135)
your_turtle.down()
main()
wn.exitonclick()
I'm trying to create a code using Python to create a STOP sign.
Here is my code:
wn = Screen()
sarah = Turtle()
sarah.penup()
sarah.left(180)
sarah.forward(50)
sarah.left(90)
sarah.forward(50)
sarah.left(90)
sarah.pendown()
for i in range(1,9):
#repeat four times
sarah.color("red")
sarah.fillcolor("red")
sarah.fill(True)
sarah.forward(100)
sarah.left(45)
sarah.fill(False)
sarah.penup()
sarah.color("white")
sarah.left(115)
sarah.forward(125)
sarah.right(100)
sarah.forward(25)
sarah.left(15)
sarah.pendown()
sarah.pendown()
sarah.forward(25)
sarah.left(15)
sarah.right(25)
sarah.left(80)
sarah.left(80)
sarah.forward(1)
sarah.left(15)
sarah.forward(35)
sarah.forward(25)
sarah.left(45)
sarah.left(15)
sarah.forward(15)
sarah.forward(10)
sarah.penup()
wn.exitonclick()
I am not clear on everything you're trying to do, but this might help you get started:
import turtle
wn = turtle.Screen()
sarah = turtle.Turtle()
turtle.setup(1000,1000)
sarah.fillcolor("red")
sarah.begin_fill()
sarah.color("red")
# Now draw an octagon
for i in range(8):
sarah.left(45)
sarah.forward(50)
sarah.end_fill()
wn.exitonclick()
Unfortunately, here's how you won't be taught to draw a stop sign using turtle graphics:
from turtle import Turtle, Screen
RADIUS = 100
FONTSIZE = int(RADIUS / 2)
FONT = ("Arial", FONTSIZE, "bold")
sarah = Turtle(visible=False)
sarah.penup()
screen = Screen()
sarah.sety(-RADIUS)
sarah.begin_poly()
sarah.circle(RADIUS, steps=8)
sarah.end_poly()
screen.register_shape("octagon", sarah.get_poly())
sarah.shape("octagon")
sarah.fillcolor("red")
sarah.home()
sarah.setheading(360 / 8 / 2)
sarah.stamp()
sarah.pencolor("white")
sarah.shapesize(0.9)
sarah.stamp()
sarah.shapesize(1.0)
sarah.sety(-FONTSIZE / 2)
sarah.write("STOP", align="center", font=FONT)
screen.exitonclick()
Most turtle examples emphasize drawing and only rarely stamping. But stamping has many advantages and can solve many problems more easily than drawing:
I probably need to write a "Joy of Stamp" tutorial...