4

I am working on a 3D finite element code, where i face the following problem:

If I take an arbitrary point (say x), how do I figure out, which element it is in?

This can be simplified to: How do I check if an arbitrary point (x) lies inside or outside of an (hexahedral) element?

What I already found:

Contrary to the two approaches above, my problem does not assume right angles nor parallel faces.

Problem sketch:

Notation: (again: though the sketch shows a regular shape, our hexahedron is assumed to be of general shape)

  • 8-node hexahedron topology, nodes: 0,..,7

  • axis: r,s,t

                      t
                      |
             4--------|-------------7
            /|        |            /|
           / |        |           / |
          /  |        |          /  |
         /   |        |         /   |
        /    |        |        /    |
       /     |        |       /     |
      5----------------------6      |
      |      |        |      |      |
      |      |        o------|---------s
      |      |       /       |      |
      |      0------/--------|------3
      |     /      /         |     /
      |    /      /          |    /
      |   /      /           |   /
      |  /      /            |  /
      | /      r             | /
      |/                     |/
      1----------------------2
    

Data that we have available:

  • coordinates of the nodes (vectors P0 to P7)
  • coordinates of the point we want to check (lets say Px)

Additionaly we assume the nodes are ordered as sketched above.

My approach/solution so far:

  1. calculate the surface (outward) normal vectors

    Use cross products, eg. for the r_pos_normal_vec (pointing out of the plane)

    r_pos_normvec = (P2-P1) x (P5-P1)

    and for the r_neg_normal_vec

    r_neg_normvec = (P4-P0) x (P3-P0)

    similarly for the s and t directions

  2. check two opposite corner nodes (I chose node0 and node 6)

    • For node0

      • calculate vector from P0 to Px:

        P0x = Px - P0

      • calculate inner prodcut of P0x and surfaces adjacent to node 0

        <P0x, r_neg_normal_vec>

        <P0x, s_neg_normal_vec>

        <P0x, t_neg_normal_vec>

    • For node1

      • same scheme as for node 0, whereas P1 instead of P0 and the positive counterparts of the normal vectors are used
  3. Iff all 6 (3 from node0 and 3 from node1) inner products result in negative value -> the point is inside the hexahedron.

Question:

I implemented the functionality described above in my code and ran some tests. It seems to work, from the math side I am quite confident.

Please discuss my approach, I am happy for any hints/clues/recommendations/bug fixes ... Is there some way to make this faster? Alternative solutions?

Note:

  • To speed up the algorithm a box check can be done first:
    • Construct a rectangular box around the hexahedron:
    • Get the min and max values of the node coordinates in each direction.
    • If the point to check (x) is outside this (larger) box, it cannot be inside the hexahedron.

4 Answers4

4

For any convex polyhedron, establish the implicit equations of the faces (f.i. plane by three points), of the form ax+by+cz+d=0.

When you plug the coordinates of a known point inside the volume (such as the center) in the expression ax+by+cz+d, you will get a set of signs. An arbitrary point is inside if it yields the same signs.


Update:

For maximum performance, you can consider also using an axis-aligned bounding box for quick rejection. This only makes sense if many of the points are outside. Make sur to use a shortcut evaluation so that early rejection can happen.

Note that a rejection test such as X<Xmin is nothing but the above sign test against the plane of equation X-Xmin=0.

  • no need to do it algebraicaly on implicit plane equations ... using vectors does the same in more conveniet way ... sign of `dot( p-p(i) , n(i) )` is the same for all sides `i` where `p(i)` is any vertex of the side and `n(i)` is its normal (cross product) ... the only condition is that all normals points the same direction (all outside or all inside) ... – Spektre May 10 '22 at 10:12
  • @Spektre: there is strictly no difference between "establishing the implicit equation" and "using vectors", you are essentially computing the same determinant in both cases. The condition that all normals point in the same direction is the same as the condition I gave (whether you update all the signs to be the same or keep them as they are is a matter of taste). Working with an internal point is a bulletproof way to avoid sign errors. –  May 10 '22 at 10:21
  • I am aware of that (that is what I meant by `using vectors does the same ...`) its just people (especially rookies) do not understand what to do with equations like `ax+by+cz+d=0` in code while rewrite in vector form its straightforward ... that is also why I did not add an answer as would be the same approach (instead I upvoted yours as correct approach) – Spektre May 10 '22 at 11:21
  • @Spektre: I am a hopeless fan of optimization, so I will most of the time advertise the expressions with the lowest cost, using precomputed coefficients. –  May 10 '22 at 11:46
  • Thanks to both of you! The approach using implicit equations works for more bodies with an arbitrary number of nodes / faces, I will keep that one in mind! In my special case, I know that all my bodies are hexahedrons, thus I want to utilize that knowledge as stated in my approach. I will try out and compare computation times of both ideas. Computation time is important, as I am doing finite elements and need to repeat that check algorithm a lot of times. – L. Rinderer May 12 '22 at 09:54
0

I personnally prefer your method, however there also is a way to approach the problem if the hexahedral restricted to parallelepiped. So you can transfer the coordinate of P in the frame $(0; e_1; e_2; e_3)$ to $(P_0, P_0P_1,P_0P_3,P_0P_4)$. We call it $(a,b,c)$, then the point is in that parallelepiped if $a,b,c > 0 a \in [0,1], a+b+c \in [0,1]$.

  • Yes, that is true! If you can assume that your shapes are parallelepipeds. Unfortunately, the shapes in my problem are hexahedrons of arbitrary shape. I cannot assume right angles or parallel planes. – L. Rinderer Jun 02 '22 at 17:25
  • This should be a comment, not an answer. – Jeter-work Jun 02 '22 at 20:24
0

Because you mentioned that you want to be able to handle arbitrary hexahedrons, I think that your process might be improved if you adjust your s, r, and t normals to account for having slightly warped faces. I would do this by making the following change to r normals (and similar for s and t):

r_pos_normvec = (P6-P1) x (P5-P2)

r_neg_normvec = (P7-P0) x (P4-P3)

This would be important for a case where you shifted node 6 towards node 7 (say 0.9xP6) and had a point at 0.95xP6. Without the warping correction, I believe you would erroneously determine the point as inside the hexahedron.

  • This is a good point. If my faces are skewed, my method won't work. I have to add this to the list of my assumptions. – L. Rinderer Jun 24 '22 at 08:00
0

Here is a python example :

def point_is_in_hexa(point,centers,normals):
    vect=[]
    prod=[]
    for i in range(6):
        vect.append(point-centers[i])
    vect= np.array(vect)
    for i in range(6):
        prod.append(np.dot(vect[i],normals[i]))
    prod=np.array(prod)
    if all(prod <= 0):
        is_in_hexa = 1
    else:
       is_in_hexa = -1
    return is_in_hexa

https://github.com/fgomez03/hexacheck

fgomez
  • 1
  • 1
  • Hey fgomez ! Nice approach, but I think there is some room for improvement: If the in/out test is false for one side, it is definitely out, you won't have to evaluate those terms. – L. Rinderer Jan 25 '23 at 17:18
  • Your approach uses the face-centers and the face-normals, which results in the same six checks i proposed in my question. In my example I do only have the nodes available (no face-center coordinates). As it can be assumed that the faces are flat, we follow: the outward normal is the same on over the whole face. Therefore, I can skip calculating the centers and calculate the normal vectors at the corners (and continue witch checking). – L. Rinderer Jan 25 '23 at 17:30