游戏开发中的数学问题:技能伤害的区域检测(三角形)
2023-03-07 09:47:08 时间
三角形呢,其实是一个比较复杂的判断,绘制图像倒还好说,就是三个点,直接就可以绘制出来一个三角形,不过为了将问题简单化,所以还是老样子,我们的三角形三个点的Y轴都是0.
1using System.Collections;
2using System.Collections.Generic;
3using UnityEngine;
4
5public class Triangle : MonoBehaviour
6{
7 public Transform pos1;
8 public Transform pos2;
9 public Transform pos3;
10
11 private void OnDrawGizmos()
12 {
13 Gizmos.DrawLine(pos1.position, pos2.position);
14 Gizmos.DrawLine(pos2.position, pos3.position);
15 Gizmos.DrawLine(pos3.position, pos1.position);
16 }
17}
太简单了,就不放图片了.反正各位都能看出来
好的,接下来就要说到比较复杂的东西了,其实讲出来也不算复杂,只是初中的知识.判断一个点是否在三角形内,大概有3种办法
第一种办法:内角和法
连接P点和三角形的三个顶点,得到三条线段PA,PB和PC,求出这三条线段与三角形各边的夹角,如果所有的夹角的内角和为180,那么就说明P点在三角形内,否则,就不在.但是这种办法如果是几何题,那么很好解,但是在我们的程序中,这个不好实现,因为需要加6个角,然后各种向量的计算.所以一般的,这种耗费性能的操作,直接舍弃掉.
第二种办法:同向法
那么同向法怎么理解呢?就是不管你是顺时针还是逆时针去遍历这些线段,会发现P点始终在这条线的一侧,如果是顺时针,那么线段就是AB ,BC ,CA ,会发现P点始终就是在你的右侧. 如果不符合这个规律,那么这个点就不在三角形内.
第三种方法重心法
三角形上的点都有这样的一个特性,假如B点,假设是A点移动了AB的一段距离,C点就是A移动了AC距离, 其中UV的取值范围为正,且U+V<1.
我们这里直接使用重心法
1using UnityEngine;
2
3public class Triangle :MonoBehaviour
4{
5
6 public Transform V1, V2, V3, Point;
7
8 private void OnDrawGizmos()
9 {
10 bool isInangle = IsPointInTriangle(V1.position , V2.position , V3.position , Point.position );
11 if (isInangle)
12 {
13 Gizmos.color = Color.red;
14 }
15 else
16 {
17 Gizmos.color = Color.blue;
18 }
19 Gizmos.DrawLine(V1.position , V2.position );
20 Gizmos.DrawLine(V2.position , V3.position );
21 Gizmos.DrawLine(V3.position , V1.position );
22 }
23
24
25
26 bool IsPointInTriangle(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 targetPoint)
27 {
28 Vector3 v0 = p2 - p1;
29 Vector3 v1 = p3 - p1;
30 Vector3 v2 = targetPoint - p1;
31
32 float _00 = Vector3.Dot(v0, v0);
33 float _01 = Vector3.Dot(v0, v1);
34 float _02 = Vector3.Dot(v0, v2);
35 float _11 = Vector3.Dot(v1, v1);
36 float _12 = Vector3.Dot(v1, v2);
37
38 float inver = 1 / (_00 * _11 - _01 * _01);
39 float u = (_11 * _02 - _01 * _12) * inver;
40 if (u < 0 || u > 1)
41 return false;
42 float v = (_00 * _12 - _01 * _02) * inver;
43 if (v < 0 || v > 1)
44 return false;
45 return u + v < 1;
46 }
47}
我们来试试效果:当点在三角形内:
当点不在三角形内:
相关文章
- 40行代码实现React核心Diff算法
- 从0开始到提交PR至OpenHarmony源仓库超详细教程
- 苹果 macOS 13 Ventura Beta 5 中 TestFlight 遇到问题,无法安装或更新测试版 App
- React 中的浅比较是如何工作的?
- Fedora 37 新功能披露
- 深入了解 EPUB 文件
- HarmonyOS应用开发:鸿蒙网络管理,网络请求获取天气信息
- 在 Manjaro 和其他基于 Arch Linux 的发行版上安装 Spotify
- 如何构建 Golang Dockerfiles?
- SpringCloud—使用分布式锁实现微服务重复请求控制
- Vue2剥丝抽茧-响应式系统之NextTick
- “作弊”:只需要知道这一个 Linux 命令就够了
- 火狐浏览器 Firefox 104 发布:新增网站耗电分析工具,可自动填写地址表单
- OpenHarmony - ArkUI(TS)开发之下拉选择菜单
- Linux 下让工作效率翻倍的四个实用技巧
- 在 GNOME 中创建你自定义的浅色和深色壁纸
- 16 图 | Nacos 架构原理①:一条注册请求会经历什么?
- 微软 Windows 11 22H2 Build 22621.457 (KB5016695) Release 预览版发布(附更新内容)
- 如何在 Linux 上设置私有 Git 服务器
- 如何在OpenHarmony上使用SeetaFace2人脸识别库?