最近项目中需要加入通过鼠标点击自由绘制多边形的功能,为了防止用户不依次选取多边形的定点,结合需求通过如下方法实现:
我们知道任意n个顶点的凸多边形可以分解成(n-2)个三角形,一个三角形的内角和是180°,所有三角形的内角和是(n-2)*180°,这一点,对于凸多边形或者凹多边形来说都是一样的,但是对于一个凸多边形来说,不存在内角大于外角,而凹多边形则会存在。
bool IsHollow(List<Vector3> curveloopPoints)
{
//使用角度和判断凹凸性:凸多边形的内角和为(n-2)*180°
var num = curveloopPoints.Count;
float angleSum = 0.0f;
for (int i = 0; i < num; i++)
{
Vector3 e1;
if (i == 0)
{
e1 = curveloopPoints[num - 1] - curveloopPoints[i];
}
else
{
e1 = curveloopPoints[i - 1] - curveloopPoints[i];
}
Vector3 e2;
if (i == num - 1)
{
e2 = curveloopPoints[0] - curveloopPoints[i];
}
else
{
e2 = curveloopPoints[i + 1] - curveloopPoints[i];
}
//标准化
e1.Normalize(); e2.Normalize();
//计算点乘
float mdot = Vector3.Dot(e1, e2);
//计算夹角弧度
float theta = Mathf.Acos(mdot);
//注意计算内角
angleSum += theta;
}
//计算内角和
float convexAngleSum = (float)((num - 2)) * Mathf.PI;
//判断凹凸性
if (angleSum < (convexAngleSum - (num * 0.00001)))
{
return true;//是凹
}
return false;//否则是凸
}