0

I'm writing code to draw squares along the circumference of a circle. I am trying to get the squares to align properly, not rotate arbitrarily. However, nothing seems to work. How do I fix this code? I have tried multiple methods, but this is what I could come up with. I also tried an alternative method wherein no centre is defined; in other words, we start drawing the circle from the circumference (and the alignment there was good). However for the next part of the question, where we have to draw concentric circles, not having a centre runs into trouble.

t.speed(0)
t.width(3)
turtle.bgcolor("grey")

def drawSquare(t, size,color):
    for i in range (0,4):
        t.forward(size)
        t.right(90)


def drawCircle(t,size, n):
    t.penup()
    t.setpos(0,0)
    t.dot(4)
    t.right(90)
    t.goto(t.pos()+(0,10))
    t.penup()
    angle=360/n

    for i in range(n):
        current=i
        t.penup()
        t.setpos(0,0)
        t.penup()
        t.forward(50)
        t.left(angle)
        t.pendown()
        parity= (current) % 2 
        print (parity)
    
        if parity == 0 : 
            color=t.color("white")
            size=30
            drawSquare(t, size,color)
            t.penup()
            t.forward(30)
            t.pendown()
        else:
            color=t.color("black")
            size=30
            drawSquare(t, size,color)
            t.penup()
            t.forward(30)
            t.pendown()
            
size=30
n=10
drawCircle(t,size,n)
turtle.done()
main()
ggorlen
  • 44,755
  • 7
  • 76
  • 106
  • 1
    Do you want the corners of the squares to line up perfectly along the circle or are the squares all supposed to be arranged without any rotation at all in a circle? I assume the first but just checking. – ggorlen Oct 18 '20 at 01:37
  • Yupp they need to line up perfectly. –  Oct 18 '20 at 02:45

2 Answers2

1

While I'm not 100% sure how the squares should line up (you can uncomment a 45 degree rotation to toggle between two approaches in the code below), there's a general pattern that seems like it gets you in the ballpark. The idea is to locate each of the n points in the circumference of the circle as follows:

for i in range(n):
    angle = 360 / n * i
    x = cos(radians(angle)) * r
    y = sin(radians(angle)) * r
    t.setpos(x, y)

For each point, begin by turning to face the origin:

t.setheading(t.towards(0, 0))

Now we're just about ready to run your square drawing routine for a point, but before that, the turtle should be placed so that it draws the box around the current location rather than using the current location as a corner. This can be achieved by moving backwards away from the center by half the square side distance, then making a leftward move by that same distance and pointing to face the origin again.

t.backward(size / 2)
t.left(90)
t.forward(size / 2)
t.right(90)

I added radius as a parameter in addition to box size for tweakability. Center x/y wouldn't be a bad addition as well but seems premature for the task at hand.

Here's the full code:

import turtle
from math import cos, radians, sin

def draw_square(t, size):
    for _ in range(4):
        t.forward(size)
        t.right(90)

def draw_squares_in_circle(t, r, size, n, colors=["black", "white"]):
    for i in range(n):
        t.color(colors[i%len(colors)])
        angle = 360 / n * i
        x = cos(radians(angle)) * r
        y = sin(radians(angle)) * r
        t.setpos(x, y)
        t.setheading(t.towards(0, 0))
        t.dot(5)
        #t.left(45) # optionally rotate the square 45 degrees
        t.backward(size / 2)
        t.left(90)
        t.forward(size / 2)
        t.right(90)
        t.pendown()
        draw_square(t, size)
        t.penup()

if __name__ == "__main__":
    turtle.bgcolor("grey")
    t = turtle.Turtle()
    t.screen.setup(500, 500)
    t.speed(1)
    t.width(3)
    t.dot(4)
    t.penup()
    draw_squares_in_circle(t, 88, 40, 10)
    turtle.exitonclick()
ggorlen
  • 44,755
  • 7
  • 76
  • 106
1

I think we can do this with less effort than either your solution or @ggorlen's using turtle's circle() method, not to draw a circle but rather to move in a circular path. We control this using its extent and sides arguments:

from turtle import Screen, Turtle
from math import pi, sin

COLORS = ['black', 'white']

def drawSquare(t, size, color):
    t.color(color)

    t.pendown()

    for _ in range(4):
        t.right(pi / 2)
        t.forward(size)

    t.penup()

def drawCircle(t, size, sides):
    angle = pi / sides
    radius = size / (2 * sin(angle))

    t.penup()
    t.dot()

    t.right(pi / 2)  # center circle() on current location
    t.forward(radius)
    t.left(pi / 2)

    for side in range(sides):
        t.circle(radius, extent=angle * 2, steps=1)

        color = COLORS[side % 2]

        t.right(angle)
        drawSquare(t, size, color)
        t.left(angle)

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

turtle = Turtle()
turtle.speed('fastest')
turtle.radians()
turtle.width(3)

drawCircle(turtle, 30, 10)

turtle.hideturtle()
screen.exitonclick()

enter image description here

cdlane
  • 40,441
  • 5
  • 32
  • 81