圆形与凸多边形
定义多边形:
/// <summary>
/// 多边形区域。
/// </summary>
public struct PolygonArea
{
public Vector2[] vertexes;
}
相交检测:
/// <summary>
/// 判断多边形与圆形相交
/// </summary>
/// <param name="polygonArea"></param>
/// <param name="target"></param>
/// <returns></returns>
public static bool PolygonS(PolygonArea polygonArea, CircleArea target)
{
if (polygonArea.vertexes.Length < 3)
{
Debug.Log("多边形边数小于3.");
return false;
}
#region 定义临时变量
//圆心
Vector2 circleCenter = target.o;
//半径的平方
float sqrR = target.r * target.r;
//多边形顶点
Vector2[] polygonVertexes = polygonArea.vertexes;
//圆心指向顶点的向量数组
Vector2[] directionBetweenCenterAndVertexes = new Vector2[polygonArea.vertexes.Length];
//多边形的边
Vector2[] polygonEdges = new Vector2[polygonArea.vertexes.Length];
for (int i = 0; i < polygonArea.vertexes.Length; i++)
{
directionBetweenCenterAndVertexes[i] = polygonVertexes[i] - circleCenter;
polygonEdges[i] = polygonVertexes[i] - polygonVertexes[(i + 1)% polygonArea.vertexes.Length];
}
#endregion
#region 以下为圆心处于多边形内的判断。
//总夹角
float totalAngle = Vector2.SignedAngle(directionBetweenCenterAndVertexes[polygonVertexes.Length - 1], directionBetweenCenterAndVertexes[0]);
for (int i = 0; i < polygonVertexes.Length - 1; i++)
totalAngle += Vector2.SignedAngle(directionBetweenCenterAndVertexes[i], directionBetweenCenterAndVertexes[i + 1]);
if (Mathf.Abs(Mathf.Abs(totalAngle) - 360f) < 0.1f)
return true;
#endregion
#region 以下为多边形的边与圆形相交的判断。
for (int i = 0; i < polygonEdges.Length; i++)
if (SegmentPointSqrDistance(polygonVertexes[i], polygonEdges[i], circleCenter) < sqrR)
return true;
#endregion
return false;
}
圆形与AABB
定义AABB:
/// <summary>
/// AABB区域
/// </summary>
public struct AABBArea
{
public Vector2 center;
public Vector2 extents;
}
AABB是凸多边形的特例,是长宽边分别与X/Y轴平行的矩形,这里我们要充分的利用他的对称性。
1 利用对称性将目标圆心映射到,以AABB中心为原点、两边为坐标轴的坐标系,的第一象限
2 将目标圆心映射到,以AABB第一象限角点为原点、两边为坐标轴的坐标系,的第一象限
3 最后只需要判断圆形半径与步骤2中映射点的向量大小
相交检测:
/// <summary>
/// 判断AABB与圆形相交
/// </summary>
/// <param name="aABBArea"></param>
/// <param name="target"></param>
/// <returns></returns>
public static bool AABB(AABBArea aABBArea, CircleArea target)
{
Vector2 v = Vector2.Max(aABBArea.center - target.o, -(aABBArea.center - target.o));
Vector2 u = Vector2.Max(v - aABBArea.extents,Vector2.zero);
return u.sqrMagnitude < target.r * target.r;
}










