从Rectangle.Intersection中查找剩余的外部矩形

时间:2017-03-29 08:11:53

标签: c# system.drawing

我有一个外部矩形和一个矩形。如何在切割相交的矩形后返回所有剩余的矩形?

2 个答案:

答案 0 :(得分:0)

我创建了这个函数,它返回一个不包含相交的List。

 private IEnumerable<Rectangle> GetExternalRectangles(Rectangle surface, Rectangle test)
    {
        var result = new List<Rectangle>();

        if (!test.IntersectsWith(surface)) return new List<Rectangle> { surface };
        #region Top and Bottom

        if (test.Top>surface.Top && test.Bottom < surface.Bottom) // test inside surface vertically
        {
            result.Add(new Rectangle(surface.Location, new Size(surface.Width, test.Top - surface.Top)));
            result.Add(new Rectangle(new Point(surface.Left,test.Bottom), new Size(surface.Width, surface.Bottom-test.Bottom)));
        }
        if (test.Top > surface.Top && test.Bottom > surface.Bottom) // test inside surface vertically, overflow bottom
        {
            result.Add(new Rectangle(surface.Location, new Size(surface.Width, test.Top - surface.Top)));
            //result.Add(new Rectangle(new Point(surface.Left,test.Bottom), new Size(surface.Width, surface.Bottom-test.Bottom)));
        }
        if (test.Top < surface.Top && test.Bottom < surface.Bottom) // test inside surface vertically, overflow top
        {
            //result.Add(new Rectangle(surface.Location, new Size(surface.Width, test.Top - surface.Top)));
            result.Add(new Rectangle(new Point(surface.Left, test.Bottom), new Size(surface.Width, surface.Bottom - test.Bottom)));
        }

        #endregion

        #region Lateral
        if (test.Left > surface.Left && test.Right < surface.Right) // test inside surface horizontally
        {
            result.Add(new Rectangle(new Point(surface.Left,Math.Max(surface.Top,test.Top)), new Size(test.Left-surface.Left, Math.Min(surface.Bottom, test.Bottom)- Math.Max(surface.Top, test.Top))));
            result.Add(new Rectangle(new Point(test.Right, Math.Max(surface.Top, test.Top)), new Size(surface.Right - test.Right, Math.Min(surface.Bottom, test.Bottom) - Math.Max(surface.Top, test.Top))));
        }
        if (test.Left > surface.Left && test.Right > surface.Right) // test inside surface horizontally, overflow right
        {
            result.Add(new Rectangle(new Point(surface.Left, Math.Max(surface.Top, test.Top)), new Size(test.Left - surface.Left, Math.Min(surface.Bottom, test.Bottom) - Math.Max(surface.Top, test.Top))));
            //result.Add(new Rectangle(new Point(test.Right, Math.Max(surface.Top, test.Top)), new Size(surface.Right - test.Right, Math.Min(surface.Bottom, test.Bottom) - Math.Max(surface.Top, test.Top))));
        }
        if (test.Left < surface.Left && test.Right < surface.Right) // test inside surface horizontally, overflow left
        {
            //result.Add(new Rectangle(new Point(surface.Left, Math.Max(surface.Top, test.Top)), new Size(test.Left - surface.Left, Math.Min(surface.Bottom, test.Bottom) - Math.Max(surface.Top, test.Top))));
            result.Add(new Rectangle(new Point(test.Right, Math.Max(surface.Top, test.Top)), new Size(surface.Right - test.Right, Math.Min(surface.Bottom, test.Bottom) - Math.Max(surface.Top, test.Top))));
        }
        #endregion
        return result;
    }

答案 1 :(得分:0)

表示这种情况的自然方式是使用Region class,例如:

var result = new Region(outer);
result.Exclude(inner);

如果您确实需要Rectangle结构列表,可以使用{1}}使用单位矩阵转换为RectangleF,然后将其转换为GetRegionScans s使用RectangleCeiling