不规则图形碰撞检测

mac2022-06-30  103

对于矩形碰撞,很多人都知道。但面对多边形图形,大多数采用多矩形覆盖的方式。 但是我不是很喜欢这种方式,我所采用的是利用一个经典算法: SAT 一种可以快速检测不规则的凸多边形是否碰撞的算法  给出两个凸多边形体,如果我们能找到一个轴线,使两物体在此轴线上的投影不重叠,则这两个物体之间没有发生碰撞,这个轴线叫做Separating Axis(红色轴线)。

 

 

 

 

对于2D来说,红色线就是垂直与多边形边的轴。 

 

 

 

因此,如果我们要检查两多边形是否碰撞,就去检查两多边形在每个所有可能的轴上的投影是否重叠。 

  

 /// <summary>

///  检测2个矩形是否发生碰撞 ///   </summary> ///   <returns></returns> public  static  bool IsIntersect (Vector2[] A, Vector2[] B)  {     Vector2 AX, AY, BX, BY;     AX =  new Vector2();     AY =  new Vector2();     BX =  new Vector2();     BY =  new Vector2();          AX.X = A[ 0].X - A[ 1].X;     AX.Y = A[ 0].Y - A[ 1].Y;                   AY.X = A[ 0].X - A[ 3].X;                  AY.Y = A[ 0].Y - A[ 3].Y;                   BX.X = B[ 0].X - B[ 1].X;                  BX.Y = B[ 0].Y - B[ 1].Y;                   BY.X = B[ 0].X - B[ 3].X;                  BY.Y = B[ 0].Y - B[ 3].Y;                    // 对于AX上:                   if (Tmp(AX, A, B))  return  false;                   if (Tmp(AY, A, B))  return  false;                  if (Tmp(BX, A, B))  return  false;                   if (Tmp(BY, A, B))  return  false;                   return  true;         }            private  static  bool Tmp(Vector2 IS,Vector2[] A,Vector2[] B)  {      float[] v =  new  float[ 4];       for ( int i =  0; i <  4; i++)     {                           float tmp = (IS.X * A[i].X + IS.Y * A[i].Y) / (IS.X * IS.X + IS.Y * IS.Y);                  v[i] = tmp * IS.X * IS.X + tmp * IS.Y * IS.Y;                 }      float[] vv =  new  float[ 4];      for ( int i =  0; i <  4; i++)     {          float tmp = (IS.X * B[i].X + IS.Y * B[i].Y) / (IS.X * IS.X + IS.Y * IS.Y);                   vv[i] = tmp * IS.X * IS.X + tmp * IS.Y * IS.Y;     }      if (Math.Max(Math.Max(v[ 0], v[ 1]),Math.Max(v[ 2],v[ 3])) >Math.Min(Math.Min(vv[ 0],vv[ 1]),Math.Min(vv[ 2],vv[ 3])) && Math.Min(Math.Min(v[ 0],v[ 1]),Math.Min(v[ 2],v[ 3])) < Math.Max(Math.Max(vv[ 0],vv[ 1]),Math.Max(vv[ 2],vv[ 3]))) {       return  false;      } // 表示暂时不知道是否碰撞                   else  return  true; // 表示知道未碰撞 } 其中需要的参数为矩形的四个点坐标(一共八个点),矩形四个点坐标要求按顺序(顺时针或者逆时针都可以)传入。(因为项目中不涉及超过四个以上顶点的检测,所以只实现了矩形的检测。)

转载于:https://www.cnblogs.com/Kurodo/archive/2012/08/08/2628688.html

最新回复(0)