Finding rectangle vertices from a parametrized plane

47 Views Asked by At

I have a set of points from an .xyz file and I need to parametrize the vertices of an identified plane. I tried using the Convex Hull function but that only returned the perimeter.

My code starts like this:

#importing data
data = np.loadtxt("Asm.xyz", dtype=float, comments="L")
x = data[:, 0]
y = data[:, 1]
z = data[:, 2]

#user selects plane of interest
plane_max = float(input("Enter the largest z-value for the plane range: "))
plane_min = float(input("Enter the smallest z-value for the plane range: "))
plane = (z >= plane_min) & (z <= plane_max)

#using linear regression to parametrize plane
X = np.column_stack((x[plane], y[plane]))
Y = z[plane]

model = LinearRegression()
model.fit(X, Y)

a, b = model.coef_
c = model.intercept_

#grab points coinciding with plane
predicted_z = a * x + b * y + c
threshold = 0.001  
on_plane_indices = np.where(np.abs(predicted_z - z) < threshold)[0]
points_on_plane = data[on_plane_indices]

#attempting to use convex hull
hull = ConvexHull(points_on_plane[:,:2])
corner_points = points_on_plane[hull.vertices]

Plotting the "vertices" and my data shows that convex hull is returning the perimeter around the planes, and not just the corners like I wanted:

Convex hull and my points plotted:

Convex hull and my points plotted

I ONLY need the corners/vertices of the rectangle. My colleague suggested I use the sklearn.decomposition.PCA function but I'm not sure if that's the right way to go.

1

There are 1 best solutions below

0
Krishnadev N On

A convex hull will most certainly not give you a rectangle, but one can start with the vertices (hull.simplices) and edges and do some geometric manipulations as described in this answer to obtain a rectangle of minimum area, which has a python implementation posted here.

Luckily for you, there even exists a ready-to-install python module MinimumBoundingBox, source available at https://bitbucket.org/william_rusnack/minimumboundingbox/. SciPy hull.simplices already gives you the vertices in order for the 2D case, and you can feed those points to the function in order to obtain the rectangle.