# ====================================================================
# draw a convex regular polygon
# --------------------------------------------------------------------
#
# points that define a regular hexagon
# (not to scale)
#
# P1
# p6 | p2
# \ | /
# \ | /
# p0
# / | \
# / | \
# p5 | P3
# P4
#
# ====================================================================
import sys
import math
import graphics as gr
import user_interface as ui
VERBOSE = False
#---------------------------------------------------------------------
# ---- create/draw a line graphics-object
# ---- Note: x0,y0,x1,y1 are graphics window coordinates
# --------------------------------------------------------------------
def draw_line(win,x0,y0,x1,y1,width=1,color='black'):
lobj = gr.Line(gr.Point(x0,y0),gr.Point(x1,y1))
lobj.setWidth(width)
lobj.setFill(color)
lobj.draw(win)
return lobj
# --------------------------------------------------------------------
# ---- create/draw a polygon (graphics-object)
# ---- draw a polygon around a center point scaled up
# ---- note: coordinates are graphics window coordinates
# --------------------------------------------------------------------
def draw_polygon(win,center_point,edges,scale,outline_width=2,
fill_color=None,outline_color='black'):
# ---- create a list of polygon points
points = []
points.append(center_point)
ang_start = 90
ang_delta = 360/edges
ang = ang_start
for i in range(edges):
x = math.cos(math.radians(ang)) * scale + center_point[0]
y = math.sin(math.radians(ang)) * scale + center_point[1]
point = (x,y,ang)
points.append(point)
ang -= ang_delta
if VERBOSE:
print()
print(f'center = {points[0]}')
print(f'scale = {scale}')
print(f'ang start = {ang_start}')
print(f'ang delta = {ang_delta}')
print(f'point list size = {len(points)}')
for idx in range(1,edges+1):
p = f'({points[idx][0]:>8.4f},{points[idx][1]:>8.4f})' +\
f' ang={points[idx][2]:<.4f}'
print(f'points[{idx}] {p}')
# ---- convert x,y window coordinates to
# ---- gr.Point objects (in a list)
gr_points = []
for idx in range(1,edges+1):
gr_points.append(gr.Point(points[idx][0],points[idx][1]))
# ---- draw a polygon
hobj = gr.Polygon(gr_points)
hobj.setOutline(outline_color)
hobj.setWidth(outline_width)
if fill_color is not None: hobj.setFill(fill_color)
hobj.draw(win)
return hobj
# --------------------------------------------------------------------
# ---- create a graphic window (with x,y axes)
# --------------------------------------------------------------------
def create_graphics_window():
win_title = 'Convex Regular Polygons'
win_width = 801
win_height = 801
win_color = 'white'
win = gr.GraphWin(win_title,win_width,win_height)
win.setBackground(win_color)
win_center_x = round(win_width/2.0)
win_center_y = round(win_height/2.0)
x_axis = draw_line(win,0,win_center_y,
win_width-1,win_center_y)
y_axis = draw_line(win,win_center_x,0,
win_center_x,win_height-1)
return (win,win_center_x,win_center_y)
# --------------------------------------------------------------------
# ---- main
# --------------------------------------------------------------------
if __name__ == '__main__':
# ----------------------------------------------------------------
# ---- get a polygon parameter (integer) from the user
# ----------------------------------------------------------------
def get_polygon_parameter(prompt):
while True:
print()
s = ui.get_user_input(prompt)
if not s: return None
tf,n = ui.is_integer(s)
if not tf:
print()
print('must enter an integer - try again')
continue
break
return n
# ---- create a graphics window
win,win_center_x,win_center_y = create_graphics_window()
# ---- user menu
while(True):
print()
print('--------------------- polygon ---------------------')
print('------------- (Integer values only) ---------------')
while True:
edges = get_polygon_parameter('enter the number of edges: ')
if edges is None: break
if edges < 3:
print()
print('must have 3 or more edges')
sys.exit()
break
while True:
scale = get_polygon_parameter('enter scale factor: ')
if scale is None: break
if scale < 50:
print()
print('error: scale must be 50 or greater')
sys.exit()
break
while True:
x = get_polygon_parameter('enter center X coord: ')
if x is None: break
if x < 20:
print()
print('error: x must be 20 or greater')
sys.exit()
break
while True:
y = get_polygon_parameter('enter center Y coord: ')
if y is None: break
if y < 20:
print()
print('error: y must be 20 or greater')
sys.exit()
break
pobj = draw_polygon(win,(x,y),edges,scale)
click = win.getMouse()
win.close()
print()