检测两个三角形是否有重叠面积/相交的方法

为什么要写这篇文章呢? 在宾夕法尼亚大学的路径规划公开课第二周的课程中, 宾夕法尼亚大学Coursera运动规划公开课学习有感之二提到的那一周的作业用到的知识. 这个问题看似简单, 但是着实花了很长时间去想. 而且, 自己拍脑袋想的东西不一定完善, 方法总是有漏洞. 所以, 最后还是去Stack Overflow上寻找的答案, 选择了一个高票答案自己研究了一下分享在这里.
下面代码来自这些网址:
1. Geometry Concepts: Line Intersection and its Applications
2. How to determine if a point is in a 2D triangle?
3. Is this a better point in triangle test (2D)?

总思路: 判断两个三角形的边不互相切割; 并且两个三角形不互相包含. 总代码在最后.

首先, 需要判断是否存在两个三角形的边互相切割的情况. 总的思路来自上面网址1. 两个三角形一共有6条边, 两两切割就是9种情况. 对于每种情况, 需要先把此时考虑的两条线段变成两条直线求交点. 然后看求出来的交点是不是在线段的横纵坐标范围内. 如果在线段的横纵坐标范围内, 就说明两条线段是有交点的; 如果不在线段的横纵坐标范围内, 就说明两条线段没有交点. 只要出现两条线段有交点, 必然说明两个三角形相交, 判断算法就可以跳出了; 否则还要继续进行其他判断. 下面是代码中的详细解释, 强烈推荐把参考的网站上面讲的知识看一遍自己推导一遍就明白后面代码了, 否则减号乘号很多时候意义并不明朗.

for i = 1:3
    for j = 1:3 %下面用到取余是为了实现j从1变化到3的时候几条边的轮换
        A1 = P1(mod(j+1, 3)+1, 2) - P1(mod(j, 3)+1, 2);
        B1 = P1(mod(j, 3)+1, 1) - P1(mod(j+1, 3)+1, 1);
        C1 = A1*P1(mod(j, 3)+1, 1)+B1*P1(mod(j, 3)+1, 2);

        A2 = P2(mod(i+1, 3)+1, 2) - P2(mod(i, 3)+1, 2);
        B2 = P2(mod(i, 3)+1, 1) - P2(mod(i+1, 3)+1, 1);
        C2 = A2*P2(mod(i, 3)+1, 1)+B2*P2(mod(i, 3)+1, 2);

        det = A1*B2 - A2*B1;

        if det == 0 % 行列式为0说明两条直线平行, 就设置交点x和y是无穷
            x = inf;
            y = inf;
        else % 否则就能够求出交点坐标
            x = (B2*C1 - B1*C2)/det;
            y = (A1*C2 - A2*C1)/det;
        end

        if (min(P1(mod(j, 3)+1, 1), P1(mod(j+1, 3)+1, 1)) <= x) && (x <= max(P1(mod(j, 3)+1, 1), P1(mod(j+1, 3)+1, 1))) && (min(P1(mod(j+1, 3)+1, 2), P1(mod(j, 3)+1, 2)) <= y) && (y <= max(P1(mod(j+1, 3)+1, 2), P1(mod(j, 3)+1, 2))) 
            if (min(P2(mod(i, 3)+1, 1), P2(mod(i+1, 3)+1, 1)) <= x) && (x <= max(P2(mod(i, 3)+1, 1), P2(mod(i+1, 3)+1, 1))) && (min(P2(mod(i+1, 3)+1, 2), P2(mod(i, 3)+1, 2)) <= y) && (y <= max(P2(mod(i+1, 3)+1, 2), P2(mod(i, 3)+1, 2))) % % 如果交点横坐标在线段横坐标之间, 交点纵坐标在两条线段纵坐标之间, 那就说明两条线段有交点
            flag1 = true;
            break;
            end
        else
            flag1 = false;
        end
    end
    if flag1 == true;
        break;
    end
end

如果两个三角形的线段之间都没有交点, 也不能说明两个三角形就不相交, 还有可能是包含的关系.
判断两个三角形是不是互相包含的关系, 就需要判断一个三角形的顶点是不是在另一个三角形里. 例如 ,三角形A的所有顶点都不在三角形B内, 三角形B的所有顶点都不在三角形A内, 这才能证明两个三角形不是互相包含关系. 下面是代码的详细解释, 资料来源来自于上面网址2的最高票答案以及网址3.
下面这个sign函数的意思是判断p1点在p2和p3点构成的线段的一侧. 通过sign函数的正负可以区分在两侧. sign函数的实现原理应该是用到了矢量的叉乘. 假设p1(x,y), p2(m1, n1), p3(m2, n2), 则 BA=(m1

  • 15
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值