Turning simple polygons about a point in Python Turtle - python

I need help turning polygon shapes (triangle and square) in Python turtle to match a picture.
Below I am trying to copy the image.
I specifically need help on what to add to my code given the triangle and square to have them repeat outwards like the picture. Because as of now the triangles and squares look like this (pentagon code is correct and works) All help is appreciated. Thank you.
import turtle
def polygon(turtle, side, length):
turtle.color("Blue")
for i in range(4):
turtle.backward(length)
turtle.left(side)
def polygon1(turtle, side1, length):
turtle.color("Green")
for i in range(3):
turtle.left(side1)
turtle.forward(length)
def polygon2(turtle, side2, length):
turtle.color("Red")
for i in range(5):
turtle.forward(length)
turtle.left(side2)
def main():
my_turtle = turtle.Turtle()
wn = turtle.Screen()
Bill = turtle.Turtle()
length = 100
side = 90
side1 = 120
side2 = 72
Bill.pensize(5)
Bill.speed(0)
#Pentagons
Bill.pu()
Bill.right(180)
y = -45
for i in range(5):
Bill.pu()
Bill.goto(60, y)
Bill.pd()
polygon2(Bill, side2, length)
y -= 20
#Triangle
Bill.pu()
Bill.left(240)
x = 45
for j in range(5):
Bill.pu()
Bill.goto(10, x)
Bill.pd()
polygon1(Bill, side1, length)
x += 20
#Square
Bill.pu()
Bill.left(240)
b = 6
for b in range(5):
Bill.pu()
Bill.goto(148, b)
Bill.pd()
polygon(Bill, side, length)
b -= 20
wn.exitonclick()
if __name__ == '__main__':
main()

pentagon code is correct and works
I don't believe the pentagon code is correct nor that you're approaching this in the correct way. The inner three shapes should form an equilateral triangle -- yours don't as you're eyeballing instead of calculating. Instead of trying to get the turtle to be in the right spot, why not have the turtle move forward in the direction of the sides of this central triangle, drawing polygons as it goes.
That is, embrace the drawing as a whole rather than trying to divide and conquer.
We'd need to make sure the polygon drawing code restores the turtle's state when it's done, so it can simply move forward to the next polygon. We'll need to make explicit which numbers are arbitrary, and which are calculable. Although the original diagram appears to use at least three turtles to achieve it's result, we'll do it with one as you attempted:
from turtle import Turtle, Screen
SHAPES = [(5, "Red"), (3, "Green"), (4, "Blue")]
LENGTH = 100
DELTA = 20
REPLICATIONS = 5
THICKNESS = 5
HEIGHT = (3 ** 0.5 / 2) * LENGTH # assumes 3 shapes, should fix!
DIVISIONS = 360 / len(SHAPES)
def polygon(turtle, sides, color):
turtle.color(color)
turtle.left(90)
turtle.forward(LENGTH / 2)
for _ in range(sides):
turtle.right(360 / sides)
turtle.forward(LENGTH)
turtle.backward(LENGTH / 2) # restore turtle to original state
turtle.right(90)
wn = Screen()
bill = Turtle()
bill.speed('fastest')
bill.pensize(THICKNESS)
bill.penup()
for offset, (sides, color) in enumerate(SHAPES):
bill.setheading(-DIVISIONS * offset - 90)
bill.forward(HEIGHT / 3) # assumes 3 shapes, should fix!
for _ in range(REPLICATIONS):
bill.pendown()
polygon(bill, sides, color)
bill.penup()
bill.forward(DELTA)
bill.home()
wn.exitonclick()

Related

Trying to make two turtles move randomly in a square and saying when they're close to each other

So my assignement is to:
make a blue rectangle
write a function that makes the turle move in a random direction within an interval of 90 degrees and move forward in a random interval of 0-25
create a blue square
Move the turle to a random point in the square
Code so the turtle moves back inside the square if it leaves it
Create an additonal turle (both should have different colors)
Use the same statement to move both turtles (with the move_random function) 500 times
if the turtles are closer than 50 units - print a string that counts the number of times they are 50 units close.
This is what it should look like:
enter image description here
I've added some comments to explain my thought process
Any and all help is appreciated
The code:
EDIT: fixed the indentations, now i get the error message on the last line that the name "meet" is not defined. Also if i run the code without the last line which is supposed to print the amount of close encounters, nothing happens, no errors, but no turtles either.
import turtle
import random
#makes the jump function
def jump(t, x, y):
t.penup()
t.goto(x, y)
t.pendown()
#creares a turtle at a defined place
def make_turtle(x, y):
t = turtle.Turtle()
jump(t, x, y) # Use of the function defined above
return t
#function to create a rectangle and fill it with a color
def rectangle(x, y, width, height, color):
t = make_turtle(x, y)
t.speed(0)
t.hideturtle()
t.fillcolor(color)
t.begin_fill()
for dist in [width, height, width, height]:
t.forward(dist)
t.left(90)
t.end_fill()
#function to move turtle in a random heading (90 degree interval) between 0--25 units forward
#While also making it turn around if it is outside of the square
def move_random(t):
if abs(t.pos()[0]) >= 250 or abs(t.pos()[1]) >= 250:
target = (0, 0)
d = (0,0)
t.setheading(d)
else:
ini = t.heading()
new = rd.randint(ini - 45, ini + 45)
t.setheading(new)
t.forward(rd.randint(0, 25))
#creates the square and both turtles
t = make_turtle(0 , 0)
t.color("green")
t2 = make_turtle(0 , 0)
t2.color("black")
rectangle(-250, -250, 500, 500, "lightblue")
jump(t, rd.randint(-250, 250), rd.randint(-250, 250))
jump(t2, rd.randint(-250, 250), rd.randint(-250, 250)) #jumps the turles randomly in the square
meet = 0
for i in range(1, 501): #makes the turtles move randomly as specified above
move_random(t)
move_random(t2)
if t.distance(t2) < 50:
t.write("close")
meet += 1
print(str(meet), "close encounter") #prints the amount of times they are close to each other
if abs(t.pos()[0]) >= 250 or abs(t.pos()[1]) >= 250:
target = (0, 0)
d = (0,0)
t.setheading(d)
else:
See that function before the "else:"? You missed a tab there.

4 triangles to be aligned vertically

so I'm working on a program where i want the output to have 4 triangles with the lengths 20,40,60,80 placed vertically where the top of each triangle should be exactly halfway along the baseline of the triangle above.
I have managed to get the first two triangles correct but cannot get the top two to align the way I want. I know I am going wrong somewhere but i cannot seem to see it
from turtle import *
NUMBER_OF_SHAPES = 4
for shape in range(1, NUMBER_OF_SHAPES + 1):
#Draw a Triangle
for sides in range(3):
forward(20 * shape)
left(120)
#Move forward to start position of next triangle
penup()
left(120)
forward(20 * shape)
right(120)
pendown()
from turtle import *
import time
NUMBER_OF_SHAPES = 4
for shape in range(1, NUMBER_OF_SHAPES + 1):
#Draw a Triangle
for sides in range(5): #redraw some edges to place the cursor on the top
forward(20 * shape)
left(120)
#Move forward to start position of next triangle
penup()
right(60)
forward(10 * (shape+1)) # half of the size of the next triangle
right(180)
time.sleep(0.5)
pendown()
Think outside the triangle:
from turtle import *
for length in range(20, 100, 20):
penup()
sety(length + ycor())
pendown()
circle(-2*length/3, steps=3)
hideturtle()
exitonclick()
Here were using turtle's circle() method to achieve two goals, first to draw a triangle, steps=3, and second to draw centered triangles starting from their top point by using a negative radius. Beyond that we simply need to adjust the vertical position.
As far as your code, I believe the problem is simpler than you're trying to make it. Things get easier if we start by moving forward half the length of the triangle, and then build from there:
from turtle import *
NUMBER_OF_SHAPES = 4
for shape in range(1, NUMBER_OF_SHAPES + 1):
forward(10 * shape)
for _ in range(4):
left(120)
forward(20 * shape)
right(120)
exitonclick()
This, in combination with reversing the order of the steps in the loop, and increasing iterations to 4, leaves us centered for the next triangle.

How to create a tessellation with turtles in Python

I'm trying to create a rhombus tessellation pattern with the turtle graphics on python that looks like this image:
http://www.supercoloring.com/sites/default/files/styles/coloring_medium/public/cif/2015/01/tessellation-with-rhombus-coloring-pages.png
I thought about creating a hexagon pattern first and then dividing the hexagons into thirds. I'm not sure how I can create the hexagon pattern recursively. So far, I'm only alternating the angles of the turtles as I run the program and I don't have a definite strategy. Any advice on how to approach this?
So far, I created 3 hexagons in the center with 3 turtles and used for loops to draw the hexagons around the 3 hexagons. However, when I loop the program, the turtles trace back the same path as before and it takes a while for it to draw the others.
Here is my code so far:
import turtle
t = turtle.Turtle()
t1 = turtle.Turtle()
t2 = turtle.Turtle()
t1.left(120)
t2.left(240)
for i in (t, t1, t2):
i.speed(0)
def hex():
for b in (t, t1, t2):
for i in range(6):
b.forward(100)
b.right(60)
for i in range(3):
t.left(120)
hex()
def rep():
for i in range(3):
for a in (t, t1, t2):
a.forward(100)
a.right(60)
for i in range(6):
a.forward(100)
a.left(60)
rep()
def rep2():
for a in (t, t1, t2):
for i in range(3):
a.left(120)
a.forward(100)
a.right(60)
rep()
a.right(120)
a.forward(100)
a.right(60)
rep()
rep2()
There are many of drawing this. I would draw based the rhombus shape because it will allow you to fill them with different colors. To be able to fill each rhombus, it needs to be drawn individually. The figure contains three different rhombus shapes (they are the same rhombus in different orientation).
I will draw first row and second row. After that it is repetition of the first and second row. Here is code:
def draw_rhombus(x,y,degree,size,tilt,color):
turtle.up()
turtle.goto(x,y)
turtle.seth(tilt)
turtle.down()
turtle.pencolor('dark gray')
turtle.fillcolor(color)
turtle.begin_fill()
turtle.fd(size)
turtle.left(degree)
turtle.fd(size)
turtle.left(180-degree)
turtle.fd(size)
turtle.left(degree)
turtle.fd(size)
turtle.left(180-degree)
turtle.end_fill()
def draw_rhombus_1(x,y,size):
draw_rhombus(x,y,120,size,0,'red')
def draw_rhombus_2(x,y,size):
draw_rhombus(x,y,60,size,0,'green')
def draw_rhombus_3(x,y,size):
draw_rhombus(x,y,60,size,60,'blue')
def rt_row_1(startx,starty,size,n):
x = startx
y = starty
for i in range(n):
draw_rhombus_1(x,y,size)
x += size
draw_rhombus_3(x,y,size)
draw_rhombus_2(x,y,size)
x += 2*size
def rt_row_2(startx,starty,size,n):
x = startx
y = starty
for i in range(n):
draw_rhombus_2(x,y,size)
x += 2*size
draw_rhombus_1(x,y,size)
x += size
draw_rhombus_3(x,y,size)
size = 80
x = -400
y = -400
for i in range(800//int(round(size*math.sqrt(3)))):
rt_row_1(x,y,size,800//(size*3))
rt_row_2(x-size/2,y+size*math.sqrt(3)/2,size,800//(size*3))
y += size*math.sqrt(3)
First, let's simplify your three turtle, three function hexagonal tessellation to a single turtle, single recursive function solution:
from turtle import Screen, Turtle
OUTER_RADIUS = 100
INNER_RADIUS = 3**0.5 * OUTER_RADIUS / 2
SIDES = 6
EXTENT = 360 / SIDES
def tessellation(depth):
turtle.right(EXTENT/2)
for _ in range(SIDES):
turtle.circle(OUTER_RADIUS, EXTENT, 1)
if depth:
heading = turtle.heading()
turtle.right(90)
tessellation(depth - 1)
turtle.setheading(heading)
screen = Screen()
turtle = Turtle(visible=False)
screen.tracer(False) # because I have no patience
turtle.penup()
turtle.goto(-OUTER_RADIUS / 2, -INNER_RADIUS)
turtle.pendown()
tessellation(2)
screen.tracer(True)
screen.exitonclick()
(Increase the depth argument to fill the window.) The tessellation you really want is four (not thirds) of these patterns overlaid atop each other. Keeping our initial code the same:
screen = Screen()
turtle = Turtle(visible=False)
screen.tracer(False) # because I have no patience
turtle.penup()
turtle.color('blue')
turtle.goto(OUTER_RADIUS / 4, -1 * INNER_RADIUS / 2)
turtle.pendown()
turtle.setheading(0)
tessellation(2)
turtle.penup()
turtle.color('red')
turtle.goto(-OUTER_RADIUS / 2, -2 * INNER_RADIUS / 2)
turtle.pendown()
turtle.setheading(0)
tessellation(2)
turtle.penup()
turtle.color('yellow')
turtle.goto(OUTER_RADIUS / 4, -3 * INNER_RADIUS / 2)
turtle.pendown()
turtle.setheading(0)
tessellation(2)
turtle.penup()
turtle.color('green')
turtle.goto(-OUTER_RADIUS / 2, -4 * INNER_RADIUS / 2)
turtle.pendown()
turtle.setheading(0)
tessellation(2)
screen.tracer(True)
screen.exitonclick()

Spirograph Turtle Python

How can I play with a turtle and how can I use a turtle?
I have trouble getting the thing to work as in the picture shown below (ignore the colors).
from turtle import *
from math import *
def formulaX(R, r, p, t):
x = (R-r)*cos(t) - (r + p)*cos((R-r)/r*t)
def formulaY(R, r, p, t):
y = (R-r)*sin(t) - (r + p)*sin((R-r)/r*t)
def t_iterating(R, r, p):
t = 2*pi
up()
goto(formulaX, formulaY)
down()
while (True):
t = t + 0.01
formulaX(R, r, p, t)
formulaY(R, r, p, t)
def main():
R = int(input("The radius of the fixed circle: "))
r = int(input("The radius of the moving circle: "))
p = int(input("The offset of the pen point, between <10 - 100>: "))
if p < 10 or p > 100:
input("Incorrect value for p!")
t_iterating(R, r, p)
input("Hit enter to close...")
main()'
I am trying to make that kind of shape. Here is the coding I have done so far.
Try changing your t_iterating function to this:
def t_iterating(R, r, p):
t = 2*pi # It seems odd to me to start from 2*pi rather than 0.
down()
while t < 20*pi: # This loops while t goes from 2*pi to 20*pi.
t = t+0.01
goto(formulaX(R, r, p, t), formulaY(R, r, p, t))
up()
No! You're missing the point of the turtle! You should try to do it all with relative movements of the turtle. Think about how you would draw the shape if you were the turtle, crawling on a large floor, dragging a paintbrush from your butt.
At each small fragment of time, the turtle will perform one small iteration of a differential equation which governs the whole behavior. It is not generally wise to precompute the x y coordinates and use the turtle's GOTO function.
The turtle itself should have only relative knowledge of its surroundings. It has a direction, and a position. And these two pieces of state are modified by turning and moving.
So, think about how you would draw the spiral. Particularly, think about drawing the very first circle. As the circle appears to close, something interesting happens: it misses. It misses by a tiny little amount, which turns out to be a fraction of a circle. It is this missing curvature that closes the large pattern of circles in a circle, as they add up to one complete turn.
When the whole figure is drawn, the turtle is back to its original position and orientation.
This is my code. The color may not be exact, but here it is:
from turtle import *
from random import randint
speed(10000)
for i in range(20):
col = randint(1, 5)
if col == 1:
pencolor("orange")
elif col == 2:
pencolor("blue")
elif col == 3:
pencolor("green")
elif col == 4:
pencolor("purple")
elif col == 5:
pencolor("dark blue")
circle(50)
left(20)
This is the output:
My code is here and the function was built for automatically choosing the random colour.
from turtle import Turtle, Screen
import random
timmy = Turtle()
screen = Screen()
screen.colormode(255)
timmy.shape("turtle")
timmy.speed("fastest")
angle = [0, 90, 180, 270]
def random_color():
red = random.randint(0, 255)
green = random.randint(0, 255)
blue = random.randint(0, 255)
colour = (red, green, blue)
return colour
def draw_circles(num_of_gap):
for _ in range(int(360 / num_of_gap)):
timmy.color(random_color())
timmy.circle(100)
timmy.right(num_of_gap)
draw_circles(20)
screen.exitonclick()
Spirograph using Python Turtle with random colours
Code:
import random
from turtle import Turtle, Screen
tim = Turtle()
tim.shape("classic")
def turtle_color():
R = random.random()
G = random.random()
B = random.random()
return tim.pencolor(R, G, B)
tim.speed("fastest")
for _ in range(72):
turtle_color()
tim.circle(100)
tim.left(5)
screen = Screen()
screen.exitonclick()
Output:
You basically get the turtle to loop through the 360 degrees and you can choose two pen colours.
from turtle import Turtle, Screen
tim = Turtle()
tim.shape("turtle")
tim.color("green")
### total degrees in circle = 360
### turn left must be a divisor of 360 (1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 18, 20, 24, 30, 36, 40, 45, 60, 72, 90) NOTE: some divisors do not work as well
degrees = 360
turn_left = 12
total_circles = int(degrees / turn_left)
tim.pensize(3)
tim.speed(0)
def circle_colour1():
### choose your colour here:
tim.pencolor("pink")
tim.circle(-100)
tim.left(turn_left)
def circle_colour2():
### choose your colour here:
tim.pencolor("grey")
tim.circle(-100)
tim.left(turn_left)
for _ in range(0, int(total_circles / 2)):
circle_colour1()
circle_colour2()
screen = Screen()
screen.exitonclick()
Real basic (360°/10) is:
from turtle import Turtle as d
draw = d()
draw.speed(0)
draw.pensize(3)
for _ in range(0, 36):
draw.circle(-100)
draw.left(10)

How Can I Fill These Squares in Turtle - Python

I am trying to fill the color in these squares:
Right now the turtle only fills the corners of theses squares, not the entire square.
Here is my code:
import turtle
import time
import random
print ("This program draws shapes based on the number you enter in a uniform pattern.")
num_str = input("Enter the side number of the shape you want to draw: ")
if num_str.isdigit():
squares = int(num_str)
angle = 180 - 180*(squares-2)/squares
turtle.up
x = 0
y = 0
turtle.setpos(x,y)
numshapes = 8
for x in range(numshapes):
turtle.color(random.random(),random.random(), random.random())
x += 5
y += 5
turtle.forward(x)
turtle.left(y)
for i in range(squares):
turtle.begin_fill()
turtle.down()
turtle.forward(40)
turtle.left(angle)
turtle.forward(40)
print (turtle.pos())
turtle.up()
turtle.end_fill()
time.sleep(11)
turtle.bye()
I've tried moving around turtle.begin_fill() and end_fill() in numerous locations with no luck… Using Python 3.2.3, thanks.
I haven't really used turtle, but it looks like this may be what you want to do. Correct me if I've assumed the wrong functionality for these calls:
turtle.begin_fill() # Begin the fill process.
turtle.down() # "Pen" down?
for i in range(squares): # For each edge of the shape
turtle.forward(40) # Move forward 40 units
turtle.left(angle) # Turn ready for the next edge
turtle.up() # Pen up
turtle.end_fill() # End fill.
You're drawing a series of triangles, using begin_fill() and end_fill() for each one. What you can probably do is move your calls to begin_fill() and end_fill() outside the inner loop, so you draw a full square and then ask for it to be filled.
Use fill
t.begin_fill()
t.color("red")
for x in range(4):
t.fd(100)
t.rt(90)
t.end_fill()
Along with moving begin_fill() and end_fill() outside the loop, as several folks have mentioned, you've other issues with your code. For example, this is a no-op:
turtle.up
I.e. it doesn't do anything. (Missing parentheses.) This test:
if num_str.isdigit():
Doesn't do much for you as there is no else clause to handle the error. (I.e. when it isn't a number, the next statement simply uses the string as a number and fails.) This calculation seems a bit too complicated:
angle = 180 - 180*(squares-2)/squares
And finally there should be a cleaner way to exit the program. Let's address all these issues:
from turtle import Screen, Turtle
from random import random
NUMBER_SHAPES = 8
print("This program draws shapes based on the number you enter in a uniform pattern.")
num_str = ""
while not num_str.isdigit():
num_str = input("Enter the side number of the shape you want to draw: ")
sides = int(num_str)
angle = 360 / sides
delta_distance = 0
delta_angle = 0
screen = Screen()
turtle = Turtle()
for x in range(NUMBER_SHAPES):
turtle.color(random(), random(), random())
turtle.penup()
delta_distance += 5
turtle.forward(delta_distance)
delta_angle += 5
turtle.left(delta_angle)
turtle.pendown()
turtle.begin_fill()
for _ in range(sides):
turtle.forward(40)
turtle.left(angle)
turtle.forward(40)
turtle.end_fill()
screen.exitonclick()

Categories

Resources