public static IntRect GetBounds(this Polygons polygons) { var totalBounds = new IntRect(long.MaxValue, long.MaxValue, long.MinValue, long.MinValue); foreach (var polygon in polygons) { var polyBounds = polygon.GetBounds(); totalBounds = totalBounds.ExpandToInclude(polyBounds); } return(totalBounds); }
private void CollideWithCorners(Vector2 la, Vector2 a, Vector2 lb, Vector2 b, int bend, int recursion) { //检测递归次数 if (recursion > 10) { return; } //创建一个包括a、b、lb的矩形 IntRect intRect = IntRect.MakeFromIntVector2(room.GetTilePosition(la)); intRect.ExpandToInclude(room.GetTilePosition(a)); intRect.ExpandToInclude(room.GetTilePosition(lb)); intRect.ExpandToInclude(room.GetTilePosition(b)); intRect.Grow(1); List <Corner> cornerLst = new List <Corner>(); //左->右、下->上 逐Tile遍历 for (int left = intRect.left; left <= intRect.right; ++left) { for (int bottom = intRect.bottom; bottom <= intRect.top; ++bottom) { if (room.GetTile(left, bottom).Solid) { if (!room.GetTile(left - 1, bottom).Solid) { if (!room.GetTile(left, bottom - 1).Solid && !room.GetTile(left - 1, bottom - 1).Solid) { //左下角拐角地形 cornerLst.Add(new Corner(FloatRect.CornerLabel.D, room.MiddleOfTile(left, bottom) + new Vector2(-10f - thickness, -10f - thickness))); } if (!room.GetTile(left, bottom + 1).Solid && !room.GetTile(left - 1, bottom + 1).Solid) { //左上角拐角地形 cornerLst.Add(new Corner(FloatRect.CornerLabel.A, room.MiddleOfTile(left, bottom) + new Vector2(-10f - thickness, 10f + thickness))); } } if (!room.GetTile(left + 1, bottom).Solid) { //右下角拐角地形 if (!room.GetTile(left, bottom - 1).Solid&& !room.GetTile(left + 1, bottom - 1).Solid) { cornerLst.Add(new Corner(FloatRect.CornerLabel.C, room.MiddleOfTile(left, bottom) + new Vector2(10f + thickness, -10f - thickness))); } //右上角拐角地形 if (!room.GetTile(left, bottom + 1).Solid&& !room.GetTile(left + 1, bottom + 1).Solid) { cornerLst.Add(new Corner(FloatRect.CornerLabel.B, room.MiddleOfTile(left, bottom) + new Vector2(10f + thickness, 10f + thickness))); } } } } } Corner?nullable = new Rope.Corner?(); float f = float.MaxValue; foreach (Corner corner in cornerLst) { if (DoesLineOverlapCorner(a, b, corner) && corner.pos != la && (corner.pos != a && corner.pos != lb) && corner.pos != b && ((Utils.PointInTriangle(corner.pos, a, la, b) || Utils.PointInTriangle(corner.pos, a, lb, b) || (Utils.PointInTriangle(corner.pos, a, la, lb) || Utils.PointInTriangle(corner.pos, la, lb, b))) && Mathf.Abs(Utils.DistanceToLine(corner.pos, la, lb)) < (double)Mathf.Abs(f))) { nullable = new Rope.Corner?(corner); f = Utils.DistanceToLine(corner.pos, lastA, lastB); } } if (!nullable.HasValue) { return; } Vector2 pos = nullable.Value.pos; //增加绳子与拐点碰撞点 bends.Insert(bend, nullable.Value); Vector2 vector2 = Utils.ClosestPointOnLine(la, lb, pos); CollideWithCorners(vector2, pos, lb, b, bend + 1, recursion + 1); CollideWithCorners(la, a, vector2, pos, bend, recursion + 1); }