0

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

Community
  • 1
  • 1
webmaker
  • 456
  • 1
  • 5
  • 15

1 Answers1

2

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.

Naive way

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)
szym
  • 5,606
  • 28
  • 34