Drawing polygon with n number of sides in Python 3.2

Goose LaMoose picture Goose LaMoose · May 1, 2014 · Viewed 18.3k times · Source

I have to write a program in Python that reads the value n and draws a polygon of n sides on the screen. I can use either the turtle graphics module or graphics.py module.

I know how to draw a polygon when n = the number of points you input and then click n times on the screen, but I'm having some trouble getting an idea on how to transform a number of sides into a polygon.

Here's the code I have for the polygon with n number of points:

def newPolygon(self,cmd):
    p = eval(input("how many points"))
    print("click",p,"times")
    num = []
    for i in range(p):
        vertices = self.win.getMouse()
        num.append(vertices)

    poly = Polygon(num)
    poly.setFill(self.color)
    poly.draw(self.win)

    self.figs.append(poly)

This isn't the whole code to the program(which is 384 lines). This is just the part of the program where the draw polygon function is where self.figs = [ ] , a list of drawn figures.

Answer

Jon Betts picture Jon Betts · May 1, 2014

I'm assuming what you would like is a way of generating equal sided polygon coordinates which you can feed to your drawing program. I'm not sure which library you are using, so I'm going to stick to lists of pairs of values:

import math


def polygon(sides, radius=1, rotation=0, translation=None):
    one_segment = math.pi * 2 / sides

    points = [
        (math.sin(one_segment * i + rotation) * radius,
         math.cos(one_segment * i + rotation) * radius)
        for i in range(sides)]

    if translation:
        points = [[sum(pair) for pair in zip(point, translation)]
                  for point in points]

    return points

There's a fair bit going on in there, so I'll talk through it. The basic approach is to sweep out a circle, and put n equally spaced points on it. These will be the points of our polygon, starting at the 12 'o' clock position.

The first thing to do is work out the angle (in radians) of each wedge from the center outwards. The total number of radians in a circle is 2 pi, so our value is 2 pi / n per segment.

After that a bit of basic trig gives us our points (https://en.wikipedia.org/wiki/Trigonometry#Extending_the_definitions). At this point we scale by our desired radius, and have the opportunity to offset the rotation by a fixed amount too.

After that we translate the values by a certain amount, because you probably want your polygon in the center of the screen, not in the corner.

A few examples

print polygon(5)    # A unit pentagon

# [(0.0, 1.0), (0.9510565162951535, 0.30901699437494745), (0.5877852522924732, -0.8090169943749473), (-0.587785252292473, -0.8090169943749476), (-0.9510565162951536, 0.30901699437494723)]

print polygon(4, 100) # A square, point up, 100 from the center to the points

# [(0.0, 100.0), (100.0, 6.123233995736766e-15), (1.2246467991473532e-14, -100.0), (-100.0, -1.8369701987210297e-14)]

print polygon(4, 2, math.pi / 4, [10, 10])  # A flat square centered on 10, 10

# [[11.414213562373096, 11.414213562373096], [11.414213562373096, 8.585786437626904], [8.585786437626904, 8.585786437626904], [8.585786437626904, 11.414213562373094]]

As you can see, these are all floats, so you may need to squish these to integers before you can use them.