I am trying to use maxrect's get_maximal_rectangle
, which uses cvxpy under the hood.
With the shapely polygon: POLYGON ((0 0.95, 0 2, 2 2, 2 1.95, 0 0.95))
max_hull = shapely.wkt.loads('POLYGON ((0 0.95, 0 2, 2 2, 2 1.95, 0 0.95))') # this is a sample of a dynamically generated valid, simple, convex polygon
max_rect = get_maximal_rectangle(max_hull.exterior.coords[:-1])
print('max rectangle', max_rect)
this produces the error
Either candidate conic solvers (['CVXOPT']) do not support the cones output by the problem (ExpCone, NonNeg, Zero), or there are not enough constraints in the problem.
so I checked maxrect's github issues. someone else reported the same problem. they solved it by modifying the call to cvx solve. So, I downloaded the source and modified the call to solve: prob.solve(solver=cvxpy.CVXOPT, verbose=False, max_iters=1000, reltol=1e-9)
to just call it empty at first prob.solve()
, but that produces
Solver 'ECOS' failed. Try another solver, or solve with verbose=True for more information.
(and verbose gives me no additional detail after "Invoking solver ECOS to obtain a solution")
so I thought to use SCS. It works, actually, but here the solution values don't have the right shape(!?). the get_maximal_rectangle
function wants to return list(bottom_left[0]), list(top_right[0])
, but this raises
TypeError: 'numpy.float64' object is not iterable
if I print bottom left and top_right I see 4 values:
[-3.86442831e+01 -2.49322910e+06] [ 8.14325412e+02 -2.03083800e+06]
but its hard to treat these as coordinates because 1. they are negative, so they are not inscribed in my polygon, and 2. it seems like the solver should return the same shape as CVXOPT.
I found success in customizing this library for modern use.
prob = cvxpy.Problem(obj, constraints)
#prob.solve(solver=cvxpy.CVXOPT, verbose=False, max_iters=1000, reltol=1e-9)
prob.solve()
bottom_left = np.array(bl.value).T * scale
top_right = np.array(tr.value).T * scale
#return list(bottom_left[0]), list(top_right[0])
return bottom_left, top_right
to convert the results back into a shapely object:
pa = get_maximal_rectangle(maximum_plot.exterior.coords)
return Polygon([(pa[0][0],pa[0][1]), (pa[0][0],pa[1][1]), (pa[1][0],pa[1][1]), (pa[1][0],pa[0][1])])