判断点在三角形内部,属于三维开发中很常用的一种算法,之前搞忘记说了,前面我们判断射线与平面,如果再加上判断交点是否在三角形内的计算就更好了。
好,假设我们有个三角形,和三角形所在平面的一个点,那么怎么判断点与三角形的关系,先来个示意图,如下:
可以看的出来,如果点P在三角形内部,那么P与三角形ABC组成的六个夹角之和为180°(三角形内角和180°),如果在三角形外部,则不然。ps:这里我们不考虑signed旋转角正负号问题。
那么判断算法就很容易实现了,使用余弦定理/点积/内置API,随意怎么计算就行(还不了解计算原理的回过头去看下),下面实现一下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PointTriangle : MonoBehaviour
{
public Transform A;
public Transform B;
public Transform C;
public Transform P;
private Vector3 PosA;
private Vector3 PosB;
private Vector3 PosC;
private Vector3 PosP;
void Start()
{
}
void Update()
{
PosA = A.position;
PosB = B.position;
PosC = C.position;
PosP = P.position;
#if UNITY_EDITOR
Debug.DrawLine(PosA, PosB, Color.black);
Debug.DrawLine(PosB, PosC, Color.black);
Debug.DrawLine(PosC, PosA, Color.black);
#endif
bool result = CheckPointInTriangle(PosP, PosA, PosB, PosC);
#if UNITY_EDITOR
Color col = result ? Color.black : Color.red;
Debug.DrawLine(PosA, PosP, col);
Debug.DrawLine(PosB, PosP, col);
Debug.DrawLine(PosC, PosP, col);
#endif
}
private bool CheckPointInTriangle(Vector3 posP, Vector3 posA, Vector3 posB, Vector3 posC)
{
float angleBAP = Vector3.Angle(posB - posA, posP - posA);
float anglePAC = Vector3.Angle(posP - posA, posC - posA);
float angleACP = Vector3.Angle(posA - posC, posP - posC);
float anglePCB = Vector3.Angle(posP - posC, posB - posC);
float angleCBP = Vector3.Angle(posC - posB, posP - posB);
float anglePBA = Vector3.Angle(posP - posB, posA - posB);
float angle = angleBAP + anglePAC + angleACP + anglePCB + angleCBP + anglePBA;
#if UNITY_EDITOR
Debug.LogFormat("angle = {0}", angle);
#endif
if (Mathf.Approximately(angle, 180.0f))
{
return true;
}
return false;
}
}
效果如下:
当然还有其他方法,后面聊,现在主要看微积分在。