maio123maio - 1 year ago 122
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.

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:

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

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download