2D空间中比较两三角形相交与包含
在处理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空间中比较两三角形相交与包含的更多相关文章
- 2D空间中求两圆的交点
出处:https://stackoverflow.com/questions/19916880/sphere-sphere-intersection-c-3d-coordinates-of-colli ...
- [译]2D空间中使用四叉树Quadtree进行碰撞检测优化
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Unity2017.2.0f3 原文出处 : Quick Tip: Use Quadtrees to Detect Lik ...
- 2D空间中判断一点是否在三角形内
要注意如果是XY坐标轴的2D空间,要取差乘分量z而不是y. 实现原理是,将三角形ABC三个边(AB,BC,CA)分别与比较点判断差乘,如果这3个差乘结果表示的方向一致,说明就在三角形内. 效果: 代码 ...
- 2D空间中求一点是否在多边形内
参考自这篇博文:http://www.cnblogs.com/dabiaoge/p/4491540.html 一开始没仔细看做法,浪费了不少时间.下面是最终实现的效果: 大致流程: 1.随便选取多边形 ...
- 3D空间中射线与三角形的交叉检測算法
引言 射线Ray,在3D图形学中有非常多重要的应用.比方,pick操作就是使用射线Ray来实现的,还有诸如子弹射线的碰撞检測等等都能够使用射线Ray来完毕. 所以,在本次博客中,将会简单的像大家介绍下 ...
- 3D空间中射线与三角形的交叉检测算法【转】
引言 射线Ray,在3D图形学中有很多重要的应用.比如,pick操作就是使用射线Ray来实现的,还有诸如子弹射线的碰撞检测等等都可以使用射线Ray来完成.所以,在本次博客中,将会简单的像大家介绍下,如 ...
- 2D空间中求线段与圆的交点
出处: https://answers.unity.com/questions/366802/get-intersection-of-a-line-and-a-circle.html 测试脚本(返回值 ...
- [算法]检测空间三角形相交算法(Devillers & Guigue算法)
#pragma once //GYDevillersTriangle.h /* 快速检测空间三角形相交算法的代码实现(Devillers & Guigue算法) 博客原地址:http://bl ...
- 2D和3D空间中计算两点之间的距离
自己在做游戏的忘记了Unity帮我们提供计算两点之间的距离,在百度搜索了下. 原来有一个公式自己就写了一个方法O(∩_∩)O~,到僵尸到达某一个点之后就向另一个奔跑过去 /// <summary ...
- 2D空间的OBB碰撞实现
OBB全称Oriented bounding box,方向包围盒算法.其表现效果和Unity的BoxCollider并无二致.由于3D空间的OBB需要多考虑一些情况 这里仅关注2D空间下的OBB. 实 ...
随机推荐
- Jetty的console-capture模块
console-capture模块用于记录Jetty运行时向标准输出和标准错误写出的信息. Java的标准输出流,即System.out. Java的标准错误流,即System.err. consol ...
- C 语言数组教程:定义、访问、修改、循环遍历及多维数组解析
C 数组 数组用于将多个值存储在单个变量中,而不是为每个值声明单独的变量. 要创建数组,请定义数据类型(例如 int)并指定数组名称,后面跟着方括号 []. 要将值插入其中,请使用逗号分隔的列表,并在 ...
- 10. Conclusion
10.1 Matrix Factorizations A = LU = (Lower triangular L with 1's on the diagonal)(Upper triangular U ...
- HDC2021技术分论坛:HarmonyOS内核技术大揭秘!
作者:jikecheng,miaoxie,HarmonyOS内核技术专家 HarmonyOS整体框架分为四个层级,如图1所示.从上到下,依次为:第一层是应用层,主要涵盖系统应用.Launcher.设置 ...
- "鸿蒙生态专家面对面"三月专场等你前来!
- Centos7配置vnc
VNC服务:VNC(Virtual Network Console)是虚拟网络控制台的缩写.它 是一款优秀的远程控制工具软件,由著名的 AT&T 的欧洲研究实验室开发的.VNC 是在基于 UN ...
- redis 简单整理——redis 的集合基本结构和命令[五]
前言 简单介绍一下集合的基本结构和命令. 正文 集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一 样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过 索引下标获取元素. ...
- .Net core 3.0 SignalR+Vue 实现简单的IM(无jq依赖)
.Net core 中的SignalR JavaScript客户端已经不需要依赖Jquery了 一.服务端 1.nuget安装 Microsoft.AspNetCore.SignalR2.在start ...
- 力扣598(java)-范围求和Ⅱ(简单)
题目: 给你一个 m x n 的矩阵 M ,初始化时所有的 0 和一个操作数组 op ,其中 ops[i] = [ai, bi] 意味着当所有的 0 <= x < ai 和 0 <= ...
- P9562 [SDCPC2023] G-Matching 题解
题目描述 给定长度为 \(n\) 的整数序列 \(a_1, a_2, \cdots, a_n\),我们将从该序列中构造出一张无向图 \(G\).具体来说,对于所有 \(1 \le i < j \ ...