In [this][1] reference we have an algorithm to determine the smallest circle containing a convex polygon. Follows a python code which uses this algorithm to find the smallest semi-circle container. The focused example is the same referenced in the OP in the cited paper. I hope the script is self explained. I am a early python programmer... import math import numpy as np from numpy import linalg as LA import matplotlib.pyplot as plt from shapely.geometry import Polygon data0 = [[2.30, 0.15],[0.63, 0.41],[0.37, 0.59],[0.79, 1.47],[2.32, 1.87],[3.6107, 0.72],[2.73, 0.14]] def sub(p1,p2): return list(map(lambda i, j: i-j,p1,p2)) def add(p1,p2): return list(map(lambda i, j: i+j,p1,p2)) def cline(p,v,u): v = [element * u for element in v] return list(map(lambda i, j: i+j,p,v)) def max_secant(data): n = len(data) dmax = 0 for i in range(n): for j in range(i): d = LA.norm(sub(data[i],data[j])) if d > dmax: dmax = d i0 = i j0 = j return (i0, j0) def verify(data, feasible): internal = True error = 0.005 for i in range(len(data)): dif = LA.norm(sub(data[i],feasible[0]))-feasible[1] if dif > error: internal = False return internal def polar_form(triangle): (x1,y1) = triangle[0] (x2,y2) = triangle[1] (x3,y3) = triangle[2] M = np.array([[2*(x2-x1),2*(y2-y1)],[2*(x2-x3),2*(y2-y3)]]) b = np.array([-(x1**2-x2**2+y1**2-y2**2),-(x3**2-x2**2+y3**2-y2**2)]) (x0, y0) = list(np.linalg.solve(M,b)) r = LA.norm([x1-x0,y1-y0]) return [[x0,y0], r] def collect_triangles(data, i0, j0): triangs = [] for i in range(len(data)): if i not in [i0, j0]: triangs.append([data[i0],data[i],data[j0]]) return triangs def rotate(data): data0 = [] n = len(data) dummy = data[0] for i in range(n-1): data0.append(data[i+1]) data0.append(dummy) return data0 def take_extremals(data): breaks = [] sant = 1 v = sub(data[1],data[0]) n = len(data) for i in range(1,n-2): s = np.sign(np.dot(v,sub(data[i+1],data[i]))) if (sant != s): breaks.append(i) sant = s if len(breaks) == 1: breaks.append(n-1) return breaks def mirror(data, p, v): reflected = [] vn = LA.norm(v) n = len(data) v = [v[0]/vn,v[1]/vn] for i in range(n): v0 = np.dot(sub(data[i],p),v) v1 = [v[0]*v0,v[1]*v0] v2 = add(p, v1) v2 = [2*v2[0],2*v2[1]] pr = sub(v2, data[i]) reflected.append(pr) return reflected def glue(data1, data2): sdata = [] n1 = len(data1) for i in range(n1): sdata.append(data1[i]) n2 = len(data2) for i in range(n2): sdata.append(data2[n2-i-1]) return sdata def select(data, k1, k2): datas = [] for i in range(k1, k2+1): datas.append(data[i]) return datas def best_circle(data1): (k1, k2) = take_extremals(data1) p0b = data1[0] vb = sub(data1[1],data1[0]) datas = select(data1, k1, k2) datam = mirror(datas,p0b,vb) dataf = glue(datam, datas) (i0, j0) = max_secant(dataf) v = sub(dataf[i0],dataf[j0]) r = 0.5*LA.norm(v) p1 = add(dataf[i0],dataf[j0]) p0 = [element*0.5 for element in p1] triangles = collect_triangles(dataf,i0,j0) polar = [] polar.append([p0,r]) for i in range(len(triangles)): polar.append(polar_form(triangles[i])) feasible = [] for i in range(len(polar)): if verify(dataf,polar[i]): feasible.append(polar[i]) bestr = math.inf for i in range(len(feasible)): [pc, r] = feasible[i] if r < bestr: bestr = r bestcirc = feasible[i] return(bestcirc, p0b, vb) ######################## #### main program #### ######################## data1 = data0 circmin = math.inf for i in range(len(data0)): (circ, p0x, vx) = best_circle(data1) if circ[1] < circmin: circmin = circ[1] bestcirc = circ p0b = p0x vb = vx data1 = rotate(data1) print(bestcirc) ############################# #### plotting the result #### ############################# (figure, axes) = plt.subplots() (cx,cy) = bestcirc[0] r = bestcirc[1] poly = Polygon(data0) (x, y) = poly.exterior.xy xmin = cx - 1.1*r xmax = cx + 1.1*r ymin = cy - 1.1*r ymax = cy + 1.1*r axes.set_xlim((xmin,xmax)) axes.set_ylim((ymin,ymax)) uncolored_circle = plt.Circle( (cx,cy), r, fill = False) axes.set_aspect( 1 ) axes.add_artist( uncolored_circle ) plt.plot(x,y) v12 = vb nv12 = LA.norm(v12) v12 = [v12[0]/nv12,v12[1]/nv12] s1x = cx - v12[0]*r s1y = cy - v12[1]*r s2x = cx + v12[0]*r s2y = cy + v12[1]*r plt.plot([s1x,s2x],[s1y,s2y]) plt.title( 'Result' ) plt.show() [1]: https://math.stackexchange.com/questions/4010764/smallest-enclosing-circle-for-a-convex-polygon/4111588#4111588