- 想法
在日常生活中, 我们经常会遇到判断两个三角形是否相交的问题。
两个三角形如果不相交,那么一定存在一条直线将两个三角形分开。令这个直线等于两个三角形的六条边,如果存在一条边将两个三角形分开,则两个三角形不相交。 - GLM
线性代数库,为OpenGL而生。在这里主要是讨论算法,所以它只是一个工具而已。替代可以选择Eigen库等。 - 叉乘
通过叉乘,我们可以判断出一个向量在另一个向量的“左右”。如果之前看过GAMES101或有线性代数基础,这不难理解。 - 三维空间的二维平面
为了方便得到叉乘的结果,我们默认z轴为0.0f。这样叉乘的结果x,y均为0,只需判断z的正负即可。 - 代码
bool cross(const Triangle2d* triangle, const Triangle2d* points) {
glm::vec3 pa = triangle->point[0],
pb = triangle->point[1],
pc = triangle->point[2];
glm::vec3 p0 = points->point[0],
p1 = points->point[1],
p2 = points->point[2];
pa.z = pb.z = pc.z = p0.z = p1.z = p2.z = 0.0f;
glm::vec3 ba = pb - pa, ca = pc - pa, _0a = p0 - pa, _1a = p1- pa, _2a = p2 - pa;
glm::vec3 bc = pb - pc, ac = -ca, _0c = p0 - pc, _1c = p1 - pc, _2c = p2 - pc;
return (glm::cross(ca, ba).z < 0 && glm::cross(_0a, ba).z > 0 && glm::cross(_1a, ba).z > 0 && glm::cross(_2a, ba).z > 0) ||
(glm::cross(ca, ba).z > 0 && glm::cross(_0a, ba).z < 0 && glm::cross(_1a, ba).z < 0 && glm::cross(_2a, ba).z < 0) ||
(glm::cross(ba, ca).z > 0 && glm::cross(_0a, ca).z < 0 && glm::cross(_1a, ca).z < 0 && glm::cross(_2a, ca).z < 0) ||
(glm::cross(ba, ca).z < 0 && glm::cross(_0a, ca).z > 0 && glm::cross(_1a, ca).z > 0 && glm::cross(_2a, ca).z > 0) ||
(glm::cross(ac, bc).z > 0 && glm::cross(_0c, bc).z < 0 && glm::cross(_1c, bc).z < 0 && glm::cross(_2c, bc).z < 0) ||
(glm::cross(ac, bc).z < 0 && glm::cross(_0c, bc).z > 0 && glm::cross(_1c, bc).z > 0 && glm::cross(_2c, bc).z > 0);
}
bool IntersactJudger(const Triangle2d*& a, const Triangle2d*& b) {
return cross(a, b) || cross(b, a);
}