如何获得重叠的矩形坐标

假设我有以下重叠矩形(“a”和“b”):

aaaaaaaa aaaaccccbbbbb aaaaccccbbbbb aaaaccccbbbbb bbbbbbbbb bbbbbbbbb 

我已经看到很多关于如何计算内部矩形区域 (“c”)的想法,但是我如何获得它的实际上/左/下/右坐标呢?

调用Rectangle.Intersect

可以根据以下逻辑找到两个矩形的重叠区域的X坐标。

要找到Y坐标,请在四个假设的最后一个以及所有三个假设中用Y代替X.


假设:

  • AB是矩形(它们的边沿X轴和Y轴对齐),

  • 每个矩形由两个点( x min / y min )定义 – ( x max / y max

  • 其中x min < x maxy min < y max

  • Ax min < Bx min


案例1 – 没有重叠:

 +--------+ |A | | | +----+ | | |B | | | +----+ | | +--------+ 

Ax min < Ax max < Bx min < Bxmax⇒无重叠。


案例2 – 一些重叠:

 +--------+ |A | | +--+-+ | |B | | | +--+-+ | | +--------+ 

Ax min < Bx min < Ax max < Bxmax⇒重叠X坐标: Bx minAx max


案例3 – 完全重叠:

 +--------+ |A | | +----+ | | |B | | | +----+ | | | +--------+ 

Ax min < Bx min < Bx max < Axmax⇒重叠X坐标: Bx minBx max


PS:您实际上可以进一步简化此算法。 重叠X坐标始终是:

max( Ax minBx min ) – min( Ax maxBx max

除非第二个值小于第一个值; 这意味着没有重叠。

 static internal Rectangle intersect(Rectangle lhs, Rectangle rhs) { Dimension lhsLeft = lhs.Location.X; Dimension rhsLeft = rhs.Location.X; Dimension lhsTop = lhs.Location.Y; Dimension rhsTop = rhs.Location.Y; Dimension lhsRight = lhs.Right; Dimension rhsRight = rhs.Right; Dimension lhsBottom = lhs.Bottom; Dimension rhsBottom = rhs.Bottom; Dimension left = Dimension.max(lhsLeft, rhsLeft); Dimension top = Dimension.max(lhsTop, rhsTop); Dimension right = Dimension.min(lhsRight, rhsRight); Dimension bottom = Dimension.min(lhsBottom, rhsBottom); Point location = new Point(left, top); Dimension width = (right > left) ? (right - left) : new Dimension(0); Dimension height = (bottom > top) ? (bottom - top) : new Dimension(0); return new Rectangle(location, new Size(width, height)); } 

假设:

 Points of rectangle R1: R1.A(x,y), R1.B(x,y), R1.C(x,y), R1.D(x,y) Points of rectangle R2: R2.A(x,y), R2.B(x,y), R2.C(x,y), R2.D(x,y) Overlapping rectangle RO: RO.A(x,y), RO.B(x,y), RO.C(x,y), RO.D(x,y) Standard cartesian coordinates (positive is right and upwards). 

重叠矩形RO使用C#计算如下:

 RO.Ax = Math.Min(R1.Ax, R2.Ax); RO.Ay = Math.Max(R1.Ay, R2.Ay); RO.Cx = Math.Max(R1.Cx, R2.Cx); RO.Cy = Math.Min(R1.Cy, R2.Cy); RO.B(x,y) and RO.D(x,y) = .... 

内矩形RI:

在上面的解决方案中交换最小和最大值以重叠矩形RO。

我为我的项目使用了一个抽象validation器,并检查一些布局是否控制重叠我在布局图中创建了矩形:

 RuleFor(p => DoControlsIntersect(p.PageControls.Select(x => new Rectangle(x.Row, x.Column, x.Width, x.Height)).ToList())).Equal(false).WithMessage(OverlappingFields); private bool DoControlsIntersect(List rectangles) { return rectangles.Any(rect => rectangles.Where(r => !r.Equals(rect)).Any(r => r.IntersectsWith(rect))); }