Search code examples
pythonplane

coplanar equations of a plane


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


Solution

  • 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)