public static bool IntersectWith(this Circle _circle, Rectangle_AABB _rect) { var ex_rect = _rect.Expand(_circle.Radius, _circle.Radius); //var coners = _rect.Corners; if (ex_rect.ContainPoint(_circle.Center)) { //圆心在扩展矩形内 //如果在四个角落,只有包含该加点才算相交,否则不算 var offsetStep = new Vector2(_rect.Witdh + _circle.Radius, _rect.Height + _circle.Radius) * 0.5f; var size = new Vector2(_circle.Radius, _circle.Radius); var leftTop_rect = new Rectangle_AABB(_rect.Center + offsetStep * new Vector2(-1, 1), size); var rightTop_rect = new Rectangle_AABB(_rect.Center + offsetStep * new Vector2(1, 1), size); var leftbottom_rect = new Rectangle_AABB(_rect.Center + offsetStep * new Vector2(-1, -1), size); var rightbottom = new Rectangle_AABB(_rect.Center + offsetStep * new Vector2(1, -1), size); if (leftTop_rect.ContainPoint(_circle.Center)) { return(_circle.ContainPoint(_rect.LeftTop)); } if (rightTop_rect.ContainPoint(_circle.Center)) { return(_circle.ContainPoint(_rect.RightTop)); } if (leftbottom_rect.ContainPoint(_circle.Center)) { return(_circle.ContainPoint(_rect.LeftBottom)); } if (rightbottom.ContainPoint(_circle.Center)) { return(_circle.ContainPoint(_rect.RightBottom)); } return(true); } else { return(false);//圆心在扩展矩形外,肯定不相交 } }
public static bool IntersectWith(this Fan _fan, Rectangle_AABB _rect) { //条件一:矩形四个角落的判断 var coners = _rect.Corners; for (int i = 0; i < 4; i++) { if (_fan.ContainPoint(coners[i])) { return(true); } } //条件二:扇形的两个边点落在矩形内 if (_rect.ContainPoint(_fan.LeftCorner)) { return(true); } if (_rect.ContainPoint(_fan.RightCorner)) { return(true); } //条件三:彼此中心点 if (_rect.ContainPoint(_fan.Center)) { return(true); } if (_fan.ContainPoint(_rect.Center)) { return(true); } //条件四,矩形的边和弧相交 var begin = _fan.Center; var end = _rect.Center; var v = end - begin; //圆的方程(x - xc)^2 + ( y - yc ) ^ 2 = r^2 //线段的方程 // x = v.x * t + begin.x // y = v.y * t + begin.y //求扇形圆心和矩形的中心线段 //把线段方程代入可以得到一个二次方程 //把它化为形如 a * x^2 + 2 * b * x + c = 0 //如果 x 有解,说明相交,无解 //b^2 - a *c >= 0,有解 var dx = _fan.Center.x - begin.x; var dy = _fan.Center.y - begin.y; var sqr_r = _fan.Length * _fan.Length; var a = v.x * v.x + v.y * v.y; var b = -(dx * v.x + dy * v.y); var c = dx * dx + dy * dy - sqr_r; var d = b * b - a * c; if (d >= 0) // 有解 { var t = (-b + Mathf.Sqrt(d)) / a; var x = v.x * t + begin.x; var y = v.y * t + begin.y; var point = new Vector2(x, y); //扇形只会包含其中一个解 var left = _fan.LeftCorner; var right = _fan.RightCorner; if (_rect.ContainPoint(point) && point.Between(_fan.Center, left, right)) { return(true); } //另一个方向 t = (-b + Mathf.Sqrt(d)) / a; x = v.x * t + begin.x; y = v.y * t + begin.y; point = new Vector2(x, y); if (_rect.ContainPoint(point) && point.Between(_fan.Center, left, right)) { return(true); } } else { //无解,说明要么扇形包含矩形中心,要么矩形包含扇形圆心,否则就不相交 } return(false); }