def oriented_bounds_2D(points):
'''
Find an oriented bounding box for a set of 2D points.
Arguments
----------
points: (n,2) float, 2D points
Returns
----------
transform: (3,3) float, homogenous 2D transformation matrix to move the input set of
points to the FIRST QUADRANT, so no value is negative.
rectangle: (2,) float, size of extents once input points are transformed by transform
'''
c = ConvexHull(np.asanyarray(points))
# (n,2,3) line segments
hull = c.points[c.simplices]
# (3,n) points on the hull to check against
dot_test = c.points[c.vertices].reshape((-1,2)).T
edge_vectors = unitize(np.diff(hull, axis=1).reshape((-1,2)))
perp_vectors = np.fliplr(edge_vectors) * [-1.0,1.0]
bounds = np.zeros((len(edge_vectors), 4))
for i, edge, perp in zip(range(len(edge_vectors)),
edge_vectors,
perp_vectors):
x = np.dot(edge, dot_test)
y = np.dot(perp, dot_test)
bounds[i] = [x.min(), y.min(), x.max(), y.max()]
extents = np.diff(bounds.reshape((-1,2,2)), axis=1).reshape((-1,2))
area = np.product(extents, axis=1)
area_min = area.argmin()
offset = -bounds[area_min][0:2]
theta = np.arctan2(*edge_vectors[area_min][::-1])
transform = transformation_2D(offset, theta)
rectangle = extents[area_min]
return transform, rectangle
评论列表
文章目录