maio123maio maio123maio - 1 month ago 9
Python Question

Using turtle in Python to draw six-pointed stars with different side lengths

Hopefully I'll be able to explain this well. I'm currently using helper functions to draw a six-pointed star in the turtle graphics window of python. First, we had to create a function to draw a triangle. Here is my code:

import turtle

wn = turtle.Screen()
tess = turtle.Turtle()
tess.speed(30)


def triangle(sz):
for i in range(3):
tess.fd(sz)
tess.lt(120)


Then, we had to use the triangle function to draw a six-pointed star. Here is my code:

def sixPtdStar(sz):
triangle(sz)
tess.lt(90)
tess.pu()
tess.fd(80)
tess.rt(90)
tess.fd(120)
tess.pd()
tess.rt(180)
triangle(sz)


Now, for me, this all runs smoothly. But the parameters for our test run of those two functions was that sz = 120 (so in the shell we'd type sixPtdStar(120) and it would run. But then we had to draw a row of stars with a new function, and then a BOX outline by those rows of stars, in another function. Here is my code:

def rowOfStars(numInRow,sz):
for i in range(numInRow):
sixPtdStar(sz)
tess.pu()
tess.lt(90)
tess.fd(80)
tess.lt(90)


def sqrOfRows(numInRow, sz):
for i in range(4):
rowOfStars(numInRow, sz)
tess.rt(90)


While this accomplishes the task, it only does so if the sz = 120. And for our test run on the rowOfStars function, the parameters are supposed to be (6, 72) and for the test run on the sqrOfRows function, our parameters are supposed to be (6, 36).

So my issue is this. How can I make this work no matter what sz equals? When I run it as is (with (6, 72) for rowOfStars or (6, 36) for sqrOfRows), the pen moves too far because the triangles aren't as big anymore.

Please let me know if more info is needed! Thanks! (I'm using Python 3.5.2)

Answer

Anywhere you use a unit that has a dimension:

tess.fd(80)
tess.fd(120) # probably should be tess.fd(sz)
tess.fd(80)

you need to scale it by what ever logic you used to get from 120 (sz) to 80. However, as @wptreanor mentioned, that logic is slightly flawed as the points on your star are uneven:

enter image description here

Also, your rowOfStars() routine doesn't really draw a row of stars (math is off and the pen is in the wrong state at times.) Simply fixing the scaling won't fix this. Finally, your sqrOfRows() routine won't work until rowOfStars() is fixed, and to make it useful, you need to adjust the starting position on the screen to make room for the drawing.

Below is my rework of your code to address some of these issues. It uses a slightly different calculation of how to position from finishing the lower to starting the upper triangle so the numbers are slightly different:

from turtle import Turtle, Screen

WIDTH_RATIO = 2 * 3**0.5 / 3  # ratio of widest point in star to edge of triangle 

def triangle(size):
    for i in range(3):
        tess.fd(size)
        tess.lt(120)

def sixPtdStar(size):
    triangle(size)
    tess.lt(30)
    tess.pu()
    tess.fd(size * WIDTH_RATIO)
    tess.lt(150)
    tess.pd()
    triangle(size)

def rowOfStars(numInRow, size):
    for i in range(numInRow):
        sixPtdStar(size)
        tess.pu()
        tess.lt(90)
        tess.fd(size * WIDTH_RATIO / 2)
        tess.lt(90)
        tess.pd()

def sqrOfRows(numInRow, size):
    tess.pu()
    halfSize = numInRow * size / 2
    tess.goto(-halfSize, halfSize)  # center on screen
    tess.pd()

    for i in range(4):
        rowOfStars(numInRow, size)
        tess.rt(90)

screen = Screen()
tess = Turtle()
tess.speed("fastest")  # numbers > 10 are all equivalent, safer to use symbols 

sqrOfRows(6, 36)

screen.exitonclick()

enter image description here

Comments