Nesting Triangles using turtle - python

I am trying to nest 4 equilateral triangles of size 20, 40, 60 and 8 with an equal spacing of 7 within turtle.
Code:
from turtle import *
number_of_shapes = 4
side = 3
for spacing in range(1, number_of_shapes+1):
for sides in range(1, side+1):
forward(20*spacing)
left(360/side)
penup()
goto(-10*spacing, -7*spacing)
pendown()
I had to use -10*spacing in the goto(-10*spacing, -7*spacing) to get a near equal spacing between nested equilateral triangles. I was wondering if there was a way to just use the number 7 to achieve equal spacing.

Connect corners and you will see angel 30deg. It creates rectangular triangle with sides 10 and 7. Only 45deg creates rectangular triangle with with sides 10 and 10.
But values (10, 7) are not correct. Correct values are (10, 5.8) - but they may create spaces which don't look as good as for (10, 7) on monitors which use only integer values to display elements.
a = 10
b = 10 * tangens(30deg) = 5.8
I use these values to create space between triangels and next I draw line with angle 30 deg - it connects corners ideally. If you use b = 7 then you get your triangles and this line will not connect cornerts
from turtle import *
import math
number_of_shapes = 4
side = 3
a = 10
b = math.tan(math.radians(30)) * a
# b = 7
for spacing in range(1,number_of_shapes +1):
for sides in range(1,side+1):
forward(20*spacing)
left(360/side)
penup()
goto(-a * spacing, -b * spacing)
pendown()
left(30)
forward(100)
(10, 7) gives:
(10, 5.8) gives:
(10, 5.8) puts triangles in correct places but monitors are not ideal (they can only use integer values for x,y) so spaces between triangles may not looks as good as in your version.

This seems a classic "better living through stamping" problem. Triangles are drawn from one corner but stamped from the center, which solves the centering problem:
from turtle import Screen, Turtle
NUMBER_OF_SHAPES = 4
CURSOR_SIZE = 20
screen = Screen()
turtle = Turtle('triangle', visible=False)
turtle.fillcolor('white')
turtle.right(30) # lay bottom on horizontal
for sizing in range(NUMBER_OF_SHAPES, 0, -1):
turtle.shapesize(20 * sizing / CURSOR_SIZE)
turtle.stamp()
screen.exitonclick()
OP's drawn triangles on the left, the triangles stamped by the above code on the right:

If OP read his assignment question properly, only the bottom side of the triangles need to have a spacing of 7 :)

Related

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.

New to python - working on nested loops. I am trying to draw 4 squares from turtle import but code only draws 1

I hope someone can enlighten me on this one! I am very, very new to python and can't get my head around this one! Can you please help/explain...
I believe the following code should draw 4 squares in a row. This exercise is to learn nested loops. What it seems to be doing is to draw 4 squares on the same spot without moving forward to draw them next to each other on the same line.
# Draw Squares across page
from turtle import *
number_of_shapes = 4
for number_of_shapes in range(1, number_of_shapes + 1) :
# Draw a Square
for sides in range (1, 5) :
forward (40)
right (90)
# Move forward to start of next square
penup ()
forward (50)
pendown ()
The following works. Is there something wrong with your indentation?
#Draw Squares across page
from turtle import *
number_of_shapes = 4
for number_of_shapes in range(1, number_of_shapes + 1):
#Draw a Square
for sides in range(1, 5):
forward(40)
right(90)
#Move forward to start of next square
penup()
forward(50)
pendown()
My guess is that your code was this:
#Draw Squares across page
from turtle import *
number_of_shapes = 4
for number_of_shapes in range(1, number_of_shapes + 1):
#Draw a Square
for sides in range(1, 5):
forward(40)
right(90)
#Move forward to start of next square
penup()
forward(50)
pendown()
So rather than drawing the square and then moving, you're drawing a line and then moving.
The solution you wrote looks fine, maybe there is a problem with indentation which is most important in Python because it present code blocks like other languages do with {}. Another thing is, that your are using number_of_shapes in the first loop as iteration variable which can cause a problem since the loop save the number (1, 2, 3, 4, ...) to this variable. You can try how it works in a simple loop.
for x in range(1, 5):
print(x)
Try to change this to some different variable (for x in range(1, number_of_shapes + 1):) or some developers, if they don't need to use this variable in they code, they just use _

Turning simple polygons about a point in Python Turtle

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()

Understanding turtle circle, and arc in "Think Python"

In the interface design section in "Think Python" I need help understanding the approach to the circle and arc functions, like this:
import turtle
import polygon
bob = turtle.Turtle()
print(bob)
def polygon(t, n, length):
angle = 360 / n
for i in range(n):
t.fd(length)
t.lt(angle)
And after that, the book introduces another approach to drawing a circle by using a polygon function:
def circle(t, r):
circumference = 2 * math.pi * r
n = int(circumference / 3 ) + 1
length = circumference / n
polygon(t, n, length)
What I don't understand:
I have no idea why they define circumference to draw circle and how it works to draw a circle.
If I call the function like circle(bob, 100) then it only draws a fraction of circle not the whole circle.
I don't understand why n is needed, and how that procedure can make a circle.
I have no idea why they define circumference to draw circle and how it
take a work to draw a circle
One way we can visualize a circle is by drawing a polygon with the number of sides equal to the (integer) circumference of the circle with each side being 1 in length. For a circle of radius = 100, that would be:
polygon(bob, 628, 1) # 628 = 2 * PI * 100
which draws a nice, but slow circle:
We can speed this up by using a rougher approximation. The circle() function above arbitrarily divides the number of sides the polygon will have by 3 but then increases the length of each side by 3:
polygon(bob, 209, 3)
This is just a sightly rougher circle but draws more quickly:
If I call the function like circle(bob, 100) then it only draws a
fraction of circle not the whole circle.
I believe you're mixing up the circle() function defined above with the circle() method that comes with turtle. It was confusing of the author to reuse the "circle" name this way. The second argument to the turtle circle() method is an extent:
extent - an angle - determines which part of the
circle is drawn. If extent is not given, draw the entire circle.
If extent is not a full circle, one endpoint of the arc is the
current pen position.
So the "Think Python" function call:
circle(bob, 100)
draws a circle of radius 100:
The turtle method:
bob.circle(100, 90)
draws an arc (1/4 circle) based on a radius of 100:
I don't understand why n is needed, and how that procedure can make a
circle.
The n is the number of sides on the polygon that approximates a circle:
n = int(circumference / 3 ) + 1
length = circumference / n
polygon(t, n, length)
Starting with a radius of 100, if we replace the '3' above with 1, we'd get a polygon with more (629) sides:
n = int(circumference / 1) + 1 # n = 629
length = circumference / n # length = 0.9989
or roughly:
polygon(t, 628, 1)
Illustrated above. But if we replace '3' with '27', we'd get a circle approximated by a polygon of 24 sides:
n = int(circumference / 27 ) + 1 # n = 24
length = circumference / n # length = 26.1799
The orignal '3' value should have been an additional argument -- in the turtle.circle() method, it's roughly equivalent to the steps argument:
As the circle is approximated by an inscribed regular polygon,
steps determines the number of steps to use. If not given,
it will be calculated automatically. May be used to draw regular
polygons.
bob.circle(100, steps=12)

number of complete and partial sqare tiles needed to fill a circle

Using Python 3, I want to find out how many complete and how many partial square tiles (side length 1 unit) one would need to fill a circular area with a given radius r. Multiple partial tiles can not be summed up to form a complete tile, also the remainder of a partial tile may not be reused anywhere else.
The center of the circle will always be on a boundary between four tiles, so we can calculate the need for 1/4 of the circle and multiply it with 4.
So if e.g. r=1, there would be 0 complete and 4 partial tiles.
For r=2 the result would be 4 complete and 12 partial tiles, and so on...
What approaches could I use? The code should be as short as possible.
I think the following should do the trick. Apologies that the print statement is python 2, but I think it should be easy to convert.
import math
# Input argument is the radius
circle_radius = 2.
# This is specified as 1, but doesn't have to be
tile_size = 1.
# Make a square box covering a quarter of the circle
tile_length_1d = int(math.ceil(circle_radius / tile_size ))
# How many tiles do you need?
num_complete_tiles = 0
num_partial_tiles = 0
# Now loop over all tile_length_1d x tile_length_1d tiles and check if they
# are needed
for i in range(tile_length_1d):
for j in range(tile_length_1d):
# Does corner of tile intersect circle?
intersect_len = ((i * tile_size)**2 + (j * tile_size)**2)**0.5
# Does *far* corner intersect (ie. is the whole tile in the circle)
far_intersect_len = (((i+1) * tile_size)**2 + ((j+1) * tile_size)**2)**0.5
if intersect_len > circle_radius:
# Don't need tile, continue
continue
elif far_intersect_len > circle_radius:
# Partial tile
num_partial_tiles += 1
else:
# Keep tile. Maybe you want to store this or something
# instead of just adding 1 to count?
num_complete_tiles += 1
# Multiple by 4 for symmetry
num_complete_tiles = num_complete_tiles * 4
num_partial_tiles = num_partial_tiles * 4
print "You need %d complete tiles" %(num_complete_tiles)
print "You need %d partial tiles" %(num_partial_tiles)

Categories

Resources