Oops ignore my comment: thought of another way to do this.
For faces F1
and F2
, take F2
's points as two triangles, e.g. (p0, p1, p2)
and (p1, p2, p3)
respectively. Then take F1
's edges, i.e. (p0, p1)
, (p1, p2)
, (p2, p3)
, and (p3, p0)
, then intersect each of them with both of the triangles.
I found some code to do this: (adapted from 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.
- If one of the checks (there should be 8) returns 1, then they definitely intersect (return true immediately).
- If all of them return 0, then they don't intersect.
- If one of the checks returns 2 (the first check will probably do that) then we need a different method. Stop these checks and immediately move onto step 2.
This part is for if the polygons are coplanar (i.e. parallel and in the same plane). This time, take all of F1
's edges and all of F2
's edges; 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.
To do such an edge intersection: (adapted from https://gist.github.com/hanigamal/6556506)
A0
, A1
form the edge from F1
, and B0
, B1
from 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);
}