在处理UV重叠、CPU的ZFighting检测时会遇到2D空间中的三角形相交问题,

网上普遍是3D空间的相交解法,因此写本文研究下,不过虽然实现了需求,

但用的方法比较暴力。

效果如图:


(鼠标拖动区域处有一小三角形,与外部大三角形进行相交包含演示)

若两三角形存在线段相交,则两三角形相交,但三点都包含的情况下则无法囊括在内。

所以还需额外判断一次三点都包含的情况。

2D空间的三角形相交得从线段与线段相交做起,这里用之前的叉乘方法来检测:

https://www.cnblogs.com/hont/p/6106043.html

点是否在多边形内用的是单双数检测法:

https://www.cnblogs.com/hont/p/6105997.html

方法还是比较朴素的方法,但离线情况下使用无问题。

代码如下(Unity XZ空间):

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class RayVsTriangle : MonoBehaviour
{
public Transform a0;
public Transform b0;
public Transform c0; public Transform a1;
public Transform b1;
public Transform c1; private bool TriangleVsTriangle(Vector3 a0, Vector3 b0, Vector3 c0, Vector3 a1, Vector3 b1, Vector3 c1)
{
bool IsIntersect(Vector3 a, Vector3 b, Vector3 c, Vector3 d)
{
float crossA = Vector3.Cross(d - c, a - c).y;
float crossB = Vector3.Cross(d - c, b - c).y; if (!(crossA > 0f ^ crossB > 0f)) return false; float crossC = Vector3.Cross(b - a, c - a).y;
float crossD = Vector3.Cross(b - a, d - a).y; if (!(crossC > 0f ^ crossD > 0f)) return false; return true;
} bool IsContain(Vector3 a, Vector3 b, Vector3 c, Vector3 p0)
{
const float kRaycastLen = 100000f; Vector3 comparePoint = (c + b) * 0.5f;
Vector3 originPoint = p0;
comparePoint += (comparePoint - originPoint).normalized * kRaycastLen; int count = 0;
if (IsIntersect(a, b, originPoint, comparePoint)) ++count;
if (IsIntersect(b, c, originPoint, comparePoint)) ++count;
if (IsIntersect(c, a, originPoint, comparePoint)) ++count; return count % 2 == 1;
} if (IsIntersect(a0, b0, a1, b1)) return true;
if (IsIntersect(a0, b0, b1, c1)) return true;
if (IsIntersect(a0, b0, c1, a1)) return true; if (IsIntersect(b0, c0, a1, b1)) return true;
if (IsIntersect(b0, c0, b1, c1)) return true;
if (IsIntersect(b0, c0, c1, a1)) return true; if (IsIntersect(c0, a0, a1, b1)) return true;
if (IsIntersect(c0, a0, b1, c1)) return true;
if (IsIntersect(c0, a0, c1, a1)) return true; if (IsContain(a1, b1, c1, a0) && IsContain(a1, b1, c1, b0) && IsContain(a1, b1, c1, c0))
return true; return false;
} private void OnDrawGizmos()
{
bool isRed = TriangleVsTriangle(a0.position, b0.position, c0.position, a1.position, b1.position, c1.position); Gizmos.color = isRed ? Color.red : Color.white; Gizmos.DrawLine(a0.position, b0.position);
Gizmos.DrawLine(b0.position, c0.position);
Gizmos.DrawLine(c0.position, a0.position); Gizmos.DrawLine(a1.position, b1.position);
Gizmos.DrawLine(b1.position, c1.position);
Gizmos.DrawLine(c1.position, a1.position);
}
}

2D空间中比较两三角形相交与包含的更多相关文章

  1. 2D空间中求两圆的交点

    出处:https://stackoverflow.com/questions/19916880/sphere-sphere-intersection-c-3d-coordinates-of-colli ...

  2. [译]2D空间中使用四叉树Quadtree进行碰撞检测优化

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Unity2017.2.0f3 原文出处 : Quick Tip: Use Quadtrees to Detect Lik ...

  3. 2D空间中判断一点是否在三角形内

    要注意如果是XY坐标轴的2D空间,要取差乘分量z而不是y. 实现原理是,将三角形ABC三个边(AB,BC,CA)分别与比较点判断差乘,如果这3个差乘结果表示的方向一致,说明就在三角形内. 效果: 代码 ...

  4. 2D空间中求一点是否在多边形内

    参考自这篇博文:http://www.cnblogs.com/dabiaoge/p/4491540.html 一开始没仔细看做法,浪费了不少时间.下面是最终实现的效果: 大致流程: 1.随便选取多边形 ...

  5. 3D空间中射线与三角形的交叉检測算法

    引言 射线Ray,在3D图形学中有非常多重要的应用.比方,pick操作就是使用射线Ray来实现的,还有诸如子弹射线的碰撞检測等等都能够使用射线Ray来完毕. 所以,在本次博客中,将会简单的像大家介绍下 ...

  6. 3D空间中射线与三角形的交叉检测算法【转】

    引言 射线Ray,在3D图形学中有很多重要的应用.比如,pick操作就是使用射线Ray来实现的,还有诸如子弹射线的碰撞检测等等都可以使用射线Ray来完成.所以,在本次博客中,将会简单的像大家介绍下,如 ...

  7. 2D空间中求线段与圆的交点

    出处: https://answers.unity.com/questions/366802/get-intersection-of-a-line-and-a-circle.html 测试脚本(返回值 ...

  8. [算法]检测空间三角形相交算法(Devillers & Guigue算法)

    #pragma once //GYDevillersTriangle.h /* 快速检测空间三角形相交算法的代码实现(Devillers & Guigue算法) 博客原地址:http://bl ...

  9. 2D和3D空间中计算两点之间的距离

    自己在做游戏的忘记了Unity帮我们提供计算两点之间的距离,在百度搜索了下. 原来有一个公式自己就写了一个方法O(∩_∩)O~,到僵尸到达某一个点之后就向另一个奔跑过去 /// <summary ...

  10. 2D空间的OBB碰撞实现

    OBB全称Oriented bounding box,方向包围盒算法.其表现效果和Unity的BoxCollider并无二致.由于3D空间的OBB需要多考虑一些情况 这里仅关注2D空间下的OBB. 实 ...

随机推荐

  1. #分块,二分#洛谷 5356 [Ynoi2017] 由乃打扑克

    题目 支持区间加和区间查询第 \(k\) 小 分析 分块之后给每个整块排序,这样修改的时候整块打标记,散块直接分开把需要加的部分暴力加之后归并,就是 \(O(\sqrt{n})\) 的 查询的话,如果 ...

  2. DS-Net:可落地的动态网络,实际加速1.62倍,快改造起来 | CVPR 2021 Oral

    论文提出能够适配硬件加速的动态网络DS-Net,通过提出的double-headed动态门控来实现动态路由.基于论文提出的高性能网络设计和IEB.SGS训练策略,仅用1/2-1/4的计算量就能达到静态 ...

  3. Bash下切换conda环境

    背景:很多时候实验命令都是基于Linux系统的,但是很多人的电脑是window系统的. 使用git自带的Bash可以运行linux命令,不过有时候在bash中想使用conda环境的时候比较麻烦,具体做 ...

  4. jenkins 持续集成和交付——pipeline(五)

    前言 整理一下pipeline. 正文 介绍 什么是pipeline呢? 根据前面的所得,我们知道,以前都是模板形式,但是如果有些复杂的项目,需要用更加自定义的写法,那么就有了pipeline,也就是 ...

  5. 重学c#系列——索引器(十)

    前言 对于索引器,我们肯定不会陌生.为什么会有索引器这个东西呢?我们发现这东西很像是属性,只是通过索引方式去调用,那就慢慢揭开他的面纱吧. 正文 假设我们要对外暴露一个数组,为了体现其封装性,我们使用 ...

  6. js 是单线程吗?

    前言 在html5中,js中允许操作多个线程执行,但是不能操作dom元素,这是一个痛点. 但是在mvvm依然存在很大的作用力,因为我们只需要操作数据,在操作数据的时候委托机制在主线程中就实现了对dom ...

  7. 浅谈sparse vec检索工程化实现

    前面我们通过两篇文章: BGE M3-Embedding 模型介绍 和 Sparse稀疏检索介绍与实践 介绍了sparse 稀疏检索,今天我们来看看如何建立一个工程化的系统来实现sparse vec的 ...

  8. 02_Vue模板语法

    Vue模板语法有2大类:         1.插值语法:           功能:用于解析标签体内容.           写法:{{xxx}},xxx是js的表达式,且可以直接读取到data中的所 ...

  9. 选轻量应用服务器or云服务器ECS?一图帮你彻底区分

    简介:轻量应用服务器适合轻量级且访问量低的应用场景,更适合个人开发者.对新手小白更友好:而云服务器ECS可覆盖全业务场景(如大数据分析,深度学习等),要求用户有一定的开发技术能力. 本文首发于公众号& ...

  10. Flink 和 Iceberg 如何解决数据入湖面临的挑战

    简介: 4.17 上海站 Meetup 胡争老师分享内容:数据入湖的挑战有哪些,以及如何用 Flink + Iceberg 解决此类问题. 一.数据入湖的核心挑战 数据实时入湖可以分成三个部分,分别是 ...