Square in square in square

65 views Asked by At

This is what I've tried so far. I don't know how to center the squares so they are not getting one over the other.

import turtle

def square(t, sz):
    for i in range(4):
        t.color("hotpink")
        t.forward(sz)
        t.left(90)

wn = turtle.Screen()
wn.bgcolor("lightgreen")
alex = turtle.Turtle()
alex.pensize(3)
size = 10

for _ in range(5):
    square(alex, size)
    alex.penup()
    alex.right(90) 
    alex.left(90)
    alex.pendown()
    size += 20
3

There are 3 answers

0
Elerium115 On

Ok, this is an interesting problem to make you think how to solve it.

The code you have starts each square from the bottom left corner.

Sure, you could think what correction you need to apply at each iteration, based on the square size.

But there's a better way, encapsulate everything inside square.

If you want squares to be concentric, modify the square function so it assumes that the start position is the center and the end position is the center.

Then it will be as easy as just calling t.square inside the loop., since the square itself handles the start and end position.

Basically we will first need to move from the center to a corner with the pen up, then draw the 4 sides and finally go back to the center.

import turtle
def square(t, sz):
    # assume we start at the center of the square facing upwards,
    # so we first move to the top left corner and face downwards

    t.penup()
    t.forward(sz / 2) 
    t.left(90)
    t.forward(sz / 2)
    t.left(90)
    t.pendown()
    # here we are at the top left corner looking down

    # we draw a square
    for i in range(4):
        t.color("hotpink")
        t.forward(sz)
        t.left(90)
        
    # now we are back to the top left corner looking down,
    # we need move back to the center and looking up
    # so we leave the turtle prepared for the next square

    t.penup()
    t.right(90)
    t.backward(sz/2)
    t.right(90)
    t.backward(sz/2)
    t.pendown()
    
wn = turtle.Screen()
wn.bgcolor("lightgreen")
alex = turtle.Turtle()
alex.pensize(3)
size = 10

for _ in range(5):
    square(alex, size)
    size += 20

This is a nice example on how something that could seem hard at the beginning can be solve in an easy way if you make each iteration start with known conditions and take care to leave the system in the same conditions it found it.

0
Federicofkt On

This should do the trick:

def draw_square(t, size):
    t.penup()
    t.goto(-size / 2, -size / 2)
    t.pendown()
    for _ in range(4):
        t.forward(size)
        t.left(90)

wn = turtle.Screen()
wn.bgcolor("lightgreen")
alex = turtle.Turtle()
alex.pensize(3)


size = 100 
step = 20

for _ in range(5):
    draw_square(alex, size)
    size -= step

wn.mainloop()

0
cdlane On

An alternate approach is to use stamping instead of drawing which naturally draws squares centered around the current hot spot, avoiding any need to move the turtle to the center of the square:

from turtle import Screen, Turtle

CURSOR_SIZE = 20

screen = Screen()
screen.bgcolor('lightgreen')

turtle = Turtle()
turtle.hideturtle()
turtle.shape('square')
turtle.color('hotpink', screen.bgcolor())

for size in range(90, 0, -20):
    turtle.shapesize(size / CURSOR_SIZE, outline=3)
    turtle.stamp()

screen.exitonclick()