/// <summary> /// 检查凸多边形和圆是否重合 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static bool CheckPolygonAndCircle(CustomPolygonCollider a, CustomCircleCollider b) { //障碍物之间的碰撞不处理 if (a.mIsobstacle && b.mIsobstacle) { return(false); } List <CustomVector3> a_worldBound = a.LocalToWorldBound; bool mInit = false; //a在左 bool a_at_left = true; //偏移向量 CustomVector2 offsetvec = new CustomVector2(0, 0); //偏移值 FixedPointF offsetfac = new FixedPointF(0); //顶点连线 //斜率k List <CustomVector2> a_edges = new List <CustomVector2>(); for (int i = 0; i < a_worldBound.Count; i++) { int point1_index = i; int point2_index = (i + 1) % a_worldBound.Count; CustomVector3 offset = a_worldBound[point2_index] - a_worldBound[point1_index]; a_edges.Add(new CustomVector2(offset.x, offset.z)); } for (int i = 0; i < a_edges.Count; i++) { CustomVector2 axis = a_edges[i]; axis = Vec_normal(axis); FixedPointF x = axis.x; FixedPointF y = axis.y; FixedPointF temp = x * x + y * y; FixedPointF z = FixedPointF.Sqrt(temp); axis.x = x / z; axis.y = y / z; //求圆在法线上的投影边界 CustomVector3 vec3 = b.mTrans.Position; CustomVector2 point = new CustomVector2(vec3.x, vec3.z); FixedPointF mapPoint = CustomVector2.Dot(point, axis); FixedPointF min = mapPoint - b.mRadius; FixedPointF max = mapPoint + b.mRadius; CustomVector2 proj_b = new CustomVector2(min, max); CustomVector2 proj_a = GetMapPointMinMaxDis(a_worldBound, axis); if (!Check_Overlap(proj_a, proj_b)) { return(false); } else { bool a_at_left_temp = false; FixedPointF offsetfac_temp = new FixedPointF(0); Set_PushVec(proj_a, proj_b, ref a_at_left_temp, ref offsetfac_temp); if (!mInit) { a_at_left = a_at_left_temp; offsetfac = offsetfac_temp; offsetvec = axis; mInit = true; } else { if (offsetfac_temp < offsetfac) { a_at_left = a_at_left_temp; offsetfac = offsetfac_temp; offsetvec = axis; } } } } Push(a, b, offsetfac, offsetvec, a_at_left); return(true); }
/// <summary> /// 检查凸两个圆是否重合 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static bool CheckCircleAndCircle(CustomCircleCollider a, CustomCircleCollider b) { //障碍物之间的碰撞不处理 if (a.mIsobstacle && b.mIsobstacle) { return(false); } bool mInit = false; //a在左 bool a_at_left = true; //偏移向量 CustomVector2 offsetvec = new CustomVector2(0, 0); //偏移值 FixedPointF offsetfac = new FixedPointF(0); //圆心连线 CustomVector3 vec3 = a.mTrans.Position - b.mTrans.Position; CustomVector2 axis = new CustomVector2(vec3.x, vec3.z); FixedPointF x = axis.x; FixedPointF y = axis.y; FixedPointF temp = x * x + y * y; FixedPointF z = FixedPointF.Sqrt(temp); //圆心重合,x轴推开 if (z == FixedPointF.zero) { axis.x = new FixedPointF(1000, 1000); axis.y = new FixedPointF(0, 1000); } else { axis.x = x / z; axis.y = y / z; } CustomVector3 apos = a.mTrans.Position; CustomVector2 point = new CustomVector2(apos.x, apos.z); FixedPointF mapPoint = CustomVector2.Dot(point, axis); FixedPointF min = mapPoint - a.mRadius; FixedPointF max = mapPoint + a.mRadius; CustomVector2 proj_a = new CustomVector2(min, max); CustomVector3 bpos = b.mTrans.Position; point = new CustomVector2(bpos.x, bpos.z); mapPoint = CustomVector2.Dot(point, axis); min = mapPoint - b.mRadius; max = mapPoint + b.mRadius; CustomVector2 proj_b = new CustomVector2(min, max); if (!Check_Overlap(proj_a, proj_b)) { return(false); } else { bool a_at_left_temp = false; FixedPointF offsetfac_temp = new FixedPointF(0); Set_PushVec(proj_a, proj_b, ref a_at_left_temp, ref offsetfac_temp); if (!mInit) { a_at_left = a_at_left_temp; offsetfac = offsetfac_temp; offsetvec = axis; mInit = true; } else { if (offsetfac_temp < offsetfac) { a_at_left = a_at_left_temp; offsetfac = offsetfac_temp; offsetvec = axis; } } } Push(a, b, offsetfac, offsetvec, a_at_left); return(true); }
/// <summary> /// 检查两个凸多边形是否重合 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static bool CheckPolygonAndPolygon(CustomPolygonCollider a, CustomPolygonCollider b) { //障碍物之间的碰撞不处理 if (a.mIsobstacle && b.mIsobstacle) { return(false); } List <CustomVector3> a_worldBound = a.LocalToWorldBound; List <CustomVector3> b_worldBound = b.LocalToWorldBound; bool mInit = false; //a在左 bool a_at_left = true; //偏移向量 CustomVector2 offsetvec = new CustomVector2(0, 0); //偏移值 FixedPointF offsetfac = new FixedPointF(0); //顶点连线, //斜率k List <CustomVector2> a_edges = new List <CustomVector2>(); for (int i = 0; i < a_worldBound.Count; i++) { int point1_index = i; int point2_index = (i + 1) % a_worldBound.Count; CustomVector3 offset = a_worldBound[point2_index] - a_worldBound[point1_index]; a_edges.Add(new CustomVector2(offset.x, offset.z)); } for (int i = 0; i < a_edges.Count; i++) { CustomVector2 axis = a_edges[i]; //获得法向量 axis = Vec_normal(axis); FixedPointF x = axis.x; FixedPointF y = axis.y; FixedPointF temp = x * x + y * y; FixedPointF z = FixedPointF.Sqrt(temp); axis.x = x / z; axis.y = y / z; CustomVector2 proj_a = GetMapPointMinMaxDis(a_worldBound, axis), proj_b = GetMapPointMinMaxDis(b_worldBound, axis); if (!Check_Overlap(proj_a, proj_b)) { return(false); } else { bool a_at_left_temp = false; FixedPointF offsetfac_temp = new FixedPointF(0); Set_PushVec(proj_a, proj_b, ref a_at_left_temp, ref offsetfac_temp); if (!mInit) { a_at_left = a_at_left_temp; offsetfac = offsetfac_temp; offsetvec = axis; mInit = true; } else { if (offsetfac_temp < offsetfac) { a_at_left = a_at_left_temp; offsetfac = offsetfac_temp; offsetvec = axis; } } } } //顶点连线 //斜率k List <CustomVector2> b_edges = new List <CustomVector2>(); for (int i = 0; i < b_worldBound.Count; i++) { int point1_index = i; int point2_index = (i + 1) % b_worldBound.Count; CustomVector3 offset = b_worldBound[point2_index] - b_worldBound[point1_index]; b_edges.Add(new CustomVector2(offset.x, offset.z)); } for (int i = 0; i < b_edges.Count; i++) { CustomVector2 axis = b_edges[i]; axis = Vec_normal(axis); FixedPointF x = axis.x; FixedPointF y = axis.y; FixedPointF temp = x * x + y * y; FixedPointF z = FixedPointF.Sqrt(temp); axis.x = x / z; axis.y = y / z; CustomVector2 proj_a = GetMapPointMinMaxDis(a_worldBound, axis), proj_b = GetMapPointMinMaxDis(b_worldBound, axis); if (!Check_Overlap(proj_a, proj_b)) { return(false); } { bool a_at_left_temp = false; FixedPointF offsetfac_temp = new FixedPointF(0); Set_PushVec(proj_a, proj_b, ref a_at_left_temp, ref offsetfac_temp); if (offsetfac_temp < offsetfac) { a_at_left = a_at_left_temp; offsetfac = offsetfac_temp; offsetvec = axis; } } } Push(a, b, offsetfac, offsetvec, a_at_left); return(true); }