Join 2 non-intersecting non-convex Polygons
Question:
-
-
-
how I might approach the problem :
Find the projection of polygon B on polygon A , create a convex-hull of polygon B and the projection, and join all using shapely.ops.unary_union()
, I don’t know how to project a polygon onto another polygon.
Edit: found a solution as follows, If you have comments or a better answer please write them down:
— find nearest point on polygon A shapely.ops.nearest_points
— buffer that point with half the width of polygon B.
— find the intersection of the buffered polygon and the exterior
of polygon A
— find the convex-hull of that intersection and polygon B
— join the convex-hull with polygon A
Answers:
import cv2
from shapely.geometry import Polygon,Point,GeometryCollection
from shapely.ops import nearest_points,unary_union
cnts ,_ = cv2.findContours(im, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
polyA,polyB= [Polygon(c.reshape(-1,2)) for c in cnts]
#find width of polyB
_,(width,_),_ = cv2.minAreaRect(cnts[1])
#find nearest points
pt1,pt2= nearest_points(polyA,polyB)
# find `projection`
projection = pt1.buffer(int(width)).intersection(polyA.exterior).buffer(3) # buffer with 2 or 3 is necessary
# find convex_hull
ch = GeometryCollection([polyB.buffer(1),projection.buffer(1)]).convex_hull
# join
poly3= unary_union([polyA,ch])
-
how I might approach the problem :
Find the projection of polygon B on polygon A , create a convex-hull of polygon B and the projection, and join all usingshapely.ops.unary_union()
, I don’t know how to project a polygon onto another polygon.
Edit: found a solution as follows, If you have comments or a better answer please write them down:
— find nearest point on polygon A shapely.ops.nearest_points
— buffer that point with half the width of polygon B.
— find the intersection of the buffered polygon and the exterior
of polygon A
— find the convex-hull of that intersection and polygon B
— join the convex-hull with polygon A
import cv2
from shapely.geometry import Polygon,Point,GeometryCollection
from shapely.ops import nearest_points,unary_union
cnts ,_ = cv2.findContours(im, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
polyA,polyB= [Polygon(c.reshape(-1,2)) for c in cnts]
#find width of polyB
_,(width,_),_ = cv2.minAreaRect(cnts[1])
#find nearest points
pt1,pt2= nearest_points(polyA,polyB)
# find `projection`
projection = pt1.buffer(int(width)).intersection(polyA.exterior).buffer(3) # buffer with 2 or 3 is necessary
# find convex_hull
ch = GeometryCollection([polyB.buffer(1),projection.buffer(1)]).convex_hull
# join
poly3= unary_union([polyA,ch])