简体   繁体   English

如何在3D中检测两张脸的交集

[英]How to detect intersection of two faces in 3D

lets say 可以说

struct myFace
{
    3DPoint p0;
    3DPoint p1;
    3DPoint p2;
    3DPoint p3;
    3DPoint pNormal;

};

face1 and face2 is faces which type of myFace. face1和face2是myFace类型的面孔。

double ac = face1.pNormal * face2.pNormal;

if (!(ac<1.00000001 && ac>0.99999999) && !(ac>-1.00000001 && ac<-0.99999999)) 如果(!(ac <1.00000001 && ac> 0.99999999)&&!(ac> -1.00000001 && ac <-0.99999999))

then faces are not parallel. 则脸部不平行。

but how can detect if they do intersect or do not ? 但是如何检测它们是否相交呢?

Oops ignore my comment: thought of another way to do this. 糟糕,我无视我的评论:想到了另一种方法。


  • Step 1: 第1步:

For faces F1 and F2 , take F2 's points as two triangles , eg (p0, p1, p2) and (p1, p2, p3) respectively. 对于面F1F2 ,将F2的点视为两个三角形 ,例如分别为(p0, p1, p2)(p1, p2, p3) Then take F1 's edges, ie (p0, p1) , (p1, p2) , (p2, p3) , and (p3, p0) , then intersect each of them with both of the triangles. 然后取F1的边缘,即(p0, p1)(p1, p2)(p2, p3)(p3, p0) ,然后将它们与两个三角形相交。

I found some code to do this: (adapted from http://geomalgorithms.com/a06-_intersect-2.html ) 我找到了一些执行此操作的代码:(改编自http://geomalgorithms.com/a06-_intersect-2.html

#define SMALL_NUM   0.00000001

/* 
   returns: 0 if no intersection 
            1 if parallel but disjoint
            2 if coplanar
*/
int intersect3D_RayTriangle(Vector P0, Vector P1, Vector V0, Vector V1, Vector V2)
{
    Vector    u, v, n;              // triangle vectors
    Vector    dir, w0, w;           // ray vectors
    float     r, a, b;              // params to calc ray-plane intersect

    // get triangle edge vectors and plane normal
    u = V1 - V0;
    v = V2 - V0;
    n = cross(u, v);

    dir = P1 - P0;             // ray direction vector
    w0 = P0 - V0;
    a = -dot(n, w0);
    b = dot(n, dir);
    if (fabs(b) < SMALL_NUM)   // ray is parallel to triangle plane
        return (fabs(a) < SMALL_NUM ? 2 : 0);

    // get intersect point of ray with triangle plane
    r = a / b;
    if (r < 0.0 || r > 1.0)
        return 0;                   // => no intersect
    Vector I = R.P0 + r * dir;      // intersect point of ray and plane

    // is I inside T?
    float uu, uv, vv, wu, wv, D;
    uu = dot(u, u);
    uv = dot(u, v);
    vv = dot(v, v);
    w = I - V0;
    wu = dot(w, u);
    wv = dot(w, v);
    D = uv * uv - uu * vv;

    // get and test parametric coords
    float s, t;
    s = (uv * wv - vv * wu) / D;
    if (s < 0.0 || s > 1.0)         // I is outside T
        return 0;
    t = (uv * wu - uu * wv) / D;
    if (t < 0.0 || (s + t) > 1.0)  // I is outside T
        return 0;

    return 1;                       // I is in T
}

P0 and P1 form one of the edges from F1 , while V0 , V1 and V2 form one the F2 's triangles. P0P1形成F1的边之一,而V0V1V2形成F2的三角形之一。

  • If one of the checks (there should be 8) returns 1, then they definitely intersect (return true immediately ). 如果其中一项检查(应为8)返回1,则它们肯定相交( 立即返回true)。
  • If all of them return 0, then they don't intersect. 如果它们全部返回0,则它们不相交。
  • If one of the checks returns 2 (the first check will probably do that) then we need a different method. 如果其中一个检查返回2(第一个检查可能会执行此操作),那么我们需要一个不同的方法。 Stop these checks and immediately move onto step 2. 停止这些检查,然后立即转到步骤2。

  • Step 2: 第2步:

This part is for if the polygons are coplanar (ie parallel and in the same plane). 这部分用于多边形是否共面(即平行且在同一平面上)。 This time, take all of F1 's edges and all of F2 's edges; 这次,取F1的所有边缘和F2的所有边缘; for each of F1 's edges, check if it intersects with any of F2 's edges, and if one pair intersects then return true immediately . 对于F1的每个边缘,检查它是否与F2的任何一条边缘相交,如果一对相交,则立即返回true。

To do such an edge intersection: (adapted from https://gist.github.com/hanigamal/6556506 ) 要进行这样的边缘相交:(改编自https://gist.github.com/hanigamal/6556506

A0 , A1 form the edge from F1 , and B0 , B1 from F2 . A0A1形成F1的边缘, B0B1 F2的边缘。

int intersection(Vector A0, Vector A1, Vector B0, Vector B1)
{
   Vector dA = A1 - A0;
   Vector dB = B1 - B0;
   Vector dC = B0 - A0;

   double s = dot(cross(dC, dB), cross(dA, dB)) / norm2(cross(dA, dB));
    return (s >= 0.0 && s <= 1.0);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM