在处理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. 详解数仓对象设计中序列SEQUENCE原理与应用

    本文分享自华为云社区<GaussDB(DWS)对象设计之序列SEQUENCE原理与使用方法介绍>,作者:VV一笑. 1. 前言 适用版本:8.2.1及以上版本 序列SEQUENCE用来生成 ...

  2. #线性dp,排列组合#洛谷 2476 [SCOI2008]着色方案

    题目 分析(弱化版) 最暴力的想法就是直接维护每种颜色的个数dp, 弱化版有一个很突出的地方就是 \(c_i\leq 5\), 也就是说可以将相同个数的颜色合并按照个数dp, 设 \(dp[c1][c ...

  3. 使用OHOS SDK构建bullet

    参照OHOS IDE和SDK的安装方法配置好开发环境. 从github下载源码. 执行如下命令: git clone --depth=1 https://github.com/bulletphysic ...

  4. 看不懂来打我,vue3如何将template编译成render函数

    前言 在之前的 通过debug搞清楚.vue文件怎么变成.js文件 文章中我们讲过了vue文件是如何编译成js文件,通过那篇文章我们知道了,template编译为render函数底层就是调用了@vue ...

  5. SpringBoot常用注解整理

    @SpringBootApplication 定义在main方法入口类处,用于启动sping boot应用项目 @Target(ElementType.TYPE) @Retention(Retenti ...

  6. Spring Cloud Bus:消息总线

    Spring Cloud Bus:消息总线 SpringCloud学习教程 SpringCloud Spring Cloud Bus 使用轻量级的消息代理来连接微服务架构中的各个服务,可以将其用于广播 ...

  7. CentOS 8 安装更新国内清华大学源手记【亲测成功】

    一直和各种OS打交道,仍觉得自己是小白,故深知小白们的困惑和蛋碎,特此将安装更新源的细节和步骤做了详细整理,供大家参考.红字是命令和提示,深灰色代码框中是源配置,本文采用了清华大学CentOS 8的源 ...

  8. Avalonia 中的样式和控件主题

    在 Avalonia 中,样式是定义控件外观的一种方式,而控件主题则是一组样式和资源,用于定义应用程序的整体外观和感觉.本文将深入探讨这些概念,并提供示例代码以帮助您更好地理解它们. 样式是什么? 样 ...

  9. redis 简单整理——redis 准备篇[一]

    前言 简单整理一下redis. 正文 为什么使用redis? 速度快 1.1 内存执行 1.2 c语言编写,速度相对快一些 1.3 单线程,比较符合这种存储模式 2 丰富的数据结构 3 丰富的功能机制 ...

  10. CentOS+Django+uWSGI+Celery+Supervisor配置

    目录 背景 目录 安装 配置Supervisor 1.生成配置文件 2. 修改配置文件 3. 创建进程文件 创建 uwsgi.conf 进程文件 创建celery进程文件 启动supervisor 启 ...