My question is similar to this post although that poster is concerned with adjacent faces How to merge adjacent coplanar faces on a mesh
I am able to extract the plane equations for each triangular facet from an stl and then convert them to a numpy array
ax + by +cz = d
plane_eq=np.array([a,b,c,d])
How could I compare the plane equations and determine which ones are coplanar and eventually merge them into one large plane equation?
The sympy library has a class for this but I am not able to get it working properly with Anaconda. http://docs.sympy.org/latest/_modules/sympy/geometry/plane.html#Plane.is_coplanar
Also, I did try an approach where I took the normals and compared them with one another via the dot product
Two [a, b, c, d]
vectors representing planes are coplanar iff they are just a scalar factor multiple of each other.
You could just normalize each vector and compare.
def are_coplanar(plane1, plane2):
# planes are given as [a, b, c, d], ax+by+cz=d
return numpy.all(plane1 / length(plane1) - plane2 / length(plane2) == 0)
where length
is vector magnitude, numpy.linarlg.norm
or roll your own, length = lambda a: numpy.dot(a, a)**0.5
.
To handle the case that planes are degenerate ([0, 0, 0, 0]
), use equivalent but safe:
return numpy.all(plane1 * length(plane2) - plane2 * length(plane1) == 0)
But in general it would probably make most sense for you to normalize all plane equations (divide by length but check for degenerate), so that checking them is a simple equality.
You could also check that all ratios in plane1 / plane2
are equal, but need to properly handle zeros in plane2
:
def are_coplanar(plane1, plane2):
first = numpy.where(plane2)[0][0] # TODO: handle all zeros
return numpy.all(plane2 * plane1[first]/plane2[first] - plane1 == 0)