Question: I want to get the coordinates of a number of points that together form an octagon. For a circle this is done easily as follows: import numpy as np n = 100 x = np.cos(np.linspace(0, 2 * np.pi, n)) y = np.sin(np.linspace(0, 2 * np.pi, n)) coordinates = list(zip(x, y))  By changing n I can increase/decrease the "angularity". Now I want to do the same for an octagon. I know that an octagon has 8 sides and the angle between each side 45 degrees. Let's assume that the perimeter of the octagon is 30.72m. Each side has therefore a length of 3.79m. perimeter = 30.72 n_sides = 8 angle = 45  How can I get n coordinates that represent this octagon? Edit: With the help of the answers of @lastchance and @mozway I am able to generate an octagon. My goal is to get evenly-spaced n coordinates from the perimeter of this octagon. If n = 8 these coordinates correspond to the corners of the octagon, but I'm interested in cases where n > 8

Answer: Let's use some math.  Each triangle in the polygon is isosceles. Assuming r the radius of the containing circle and a each side of the polygon we have: n_sides = 8 perimeter = n_sides * a a/2 = sin(pi/n_sides) / r # isosceles = 2 equal right triangles perimeter = n_sides * 2 * sin(pi/n_sides) / r r = perimeter/(2 * n_sides * sin(pi/n_sides))  Thus, the coordinates are: perimeter = 30.72 n_sides = 8 r = perimeter/(2 * n_sides * np.sin(np.pi/n_sides)) x = r * np.cos(np.linspace(0, 2 * np.pi, n_sides, endpoint=False)) y = r * np.sin(np.linspace(0, 2 * np.pi, n_sides, endpoint=False))  Note the endpoint=False in linspace. As a graph: ax = plt.subplot(aspect=1) ax.plot(x, y, marker='o')  Output:  If you want one extra point to "close" the polygon (the last point being the same as the first point): x = r * np.cos(np.linspace(0, 2 * np.pi, n_sides+1)) y = r * np.sin(np.linspace(0, 2 * np.pi, n_sides+1))   Now, let's use shapely to check that the calculation is correct: from shapely.geometry import Polygon Polygon(zip(x, y)).length # 30.72   Interpolating n points on the octagon/polygon Now that we have a polygon, we can interpolate n points along its perimeter. Let's generate a "closed" polygon (i.e. n_sides+1 point in which the last one is equal to the first), create a LineString and interpolate n values along it: from shapely.geometry import LineString perimeter = 30.72 n_sides = 8 n = 12 # compute the points of the polygon r = perimeter/(2 * n_sides * np.sin(np.pi/n_sides)) x = r * np.cos(np.linspace(0, 2 * np.pi, n_sides+1)) y = r * np.sin(np.linspace(0, 2 * np.pi, n_sides+1)) # create a line string # interpolate n points on the perimeter line = LineString(zip(x, y)) coords = np.concatenate(list(line.interpolate(x).coords for x in np.linspace(0, line.length, n, endpoint=False))) # plot ax = plt.subplot(aspect=1) ax.plot(x, y) ax.plot(*coords.T, ls='', marker='o', label='n = 8')  Alternatively, performing the interpolation with numpy.interp: perimeter = 30.72 n_sides = 8 n = 12 # compute the points of the polygon r = perimeter/(2 * n_sides * np.sin(np.pi/n_sides)) x = r * np.cos(np.linspace(0, 2 * np.pi, n_sides+1)) y = r * np.sin(np.linspace(0, 2 * np.pi, n_sides+1)) # interpolate the n points along the perimeter ref = np.linspace(0, 1, n_sides+1)*perimeter # distance to origin: ref dist = np.linspace(0, 1, n+1)*perimeter # distance to origin: n points new_x = np.interp(dist, ref, x) # interpolated x new_y = np.interp(dist, ref, y) # interpolated y ax = plt.subplot(aspect=1) ax.plot(x, y) ax.plot(new_x, new_y, ls='', marker='o')  Output: