假设我有以下重叠的矩形("a"和"b"):
aaaaaaaa
aaaaccccbbbbb
aaaaccccbbbbb
aaaaccccbbbbb
bbbbbbbbb
bbbbbbbbb
我看到了很多有关如何计算内矩形(“c”)面积的想法,但是我该如何获取其实际的顶部/左侧/底部/右侧坐标?
aaaaaaaa
aaaaccccbbbbb
aaaaccccbbbbb
aaaaccccbbbbb
bbbbbbbbb
bbbbbbbbb
我看到了很多有关如何计算内矩形(“c”)面积的想法,但是我该如何获取其实际的顶部/左侧/底部/右侧坐标?
+--------+
|A |
| | +----+
| | |B |
| | +----+
| |
+--------+
A.xmin < B.xmin < A.xmax < B.xmax ⇒ Overlap.
+--------+
|A |
| +--+-+
| |B | |
| +--+-+
| |
+--------+
A.xmin < B.xmin < A.xmax < B.xmax ⇒ 重叠的X坐标: B.xmin – A.xmax
情况3 - 完全重叠:
+--------+
|A |
| +----+ |
| |B | |
| +----+ |
| |
+--------+
A.xmin < B.xmin < B.xmax < A.xmax ⇒ 重叠的X坐标: B.xmin – B.xmax
附言: 实际上,您可以进一步简化此算法。 重叠的X坐标始终为:
max(A.xmin, B.xmin) – min(A.xmax, B.xmax)
除非第二个值小于第一个值; 这意味着没有重叠。
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).
使用C#计算重叠矩形RO的方法如下:
RO.A.x = Math.Min(R1.A.x, R2.A.x);
RO.A.y = Math.Max(R1.A.y, R2.A.y);
RO.C.x = Math.Max(R1.C.x, R2.C.x);
RO.C.y = Math.Min(R1.C.y, R2.C.y);
RO.B(x,y) and RO.D(x,y) = ....
内部矩形RI:
对于重叠的矩形RO,在上述解决方案中交换最小值和最大值。
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<Rectangle> rectangles)
{
return rectangles.Any(rect => rectangles.Where(r => !r.Equals(rect)).Any(r => r.IntersectsWith(rect)));
}