2010-07-03 18 views
7

Giả sử tôi có hình chữ nhật chồng chéo sau ("a" và "b"):hình chữ nhật như thế nào để có được chồng chéo phối

aaaaaaaa 
aaaaccccbbbbb 
aaaaccccbbbbb 
aaaaccccbbbbb 
    bbbbbbbbb 
    bbbbbbbbb 

Tôi đã nhìn thấy rất nhiều ý tưởng về cách tính toán khu vực của bên trong hình chữ nhật ("c"), nhưng làm thế nào tôi sẽ đi về nhận được thực tế trên/trái/dưới/phải tọa độ cho nó?

Trả lời

4
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)); 
} 
+0

Đoạn mã trên giả định rằng các hình chữ nhật làm giao nhau. – ChrisW

+0

... miễn là hệ tọa độ có hướng từ phải sang trái như hướng dương. –

+0

@ChrisW: Để Kiểm tra xem chúng có giao nhau không: Trong tất cả các trường hợp chúng KHÔNG giao nhau, chúng giao nhau. Chúng không giao nhau nếu không có StartA> EndB (hoàn toàn sau B) hoặc EndA Không A Và Không B ==> (StartA <= EndB) và (EndA> = StartB), trong bất kỳ trường hợp nào khác, trả về hình chữ nhật (0,0,0,0) hoặc NULL. –

9

Tọa độ X của vùng chồng chéo của hai hình chữ nhật có thể được tìm thấy theo logic sau đây.

Để tìm tọa độ Y, thay thế Y cho X trong cuối cùng của bốn giả định, cũng như trong cả ba trường hợp.


Giả định:

  • MộtB là hình chữ nhật (với bên họ thẳng hàng dọc theo trục X và Y),

  • mỗi hình chữ nhật là được xác định bởi hai điểm   (x phút/y phút) – (x max/y max)

  • nơi x phút < x max   và   y phút < y tối đa  .

  • A.x phút < B.x phút


Trường hợp 1 — Không chồng chéo:

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

A.x phút < A.x max < B.x phút < B.x max   ⇒   Không chồng chéo.


Trường hợp 2 — Một số chồng chéo:

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

A.x phút < B.x phút < A.x max < B.x max   ⇒   chồng chéo X phối: B.x phútA.x max


Trường hợp 3 — Complete chồng chéo:

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

A.x phút < B.x phút < B.x max < A.x max   ⇒   chồng chéo X phối: B.x phútB.x max


P.S .: Bạn có thể thực sự tiếp tục đơn giản hóa thuật toán này. Các tọa độ chồng chéo X luôn:

max (Axe phút, Bx phút) – min (Axe max, Bx max)

trừ khi giá trị thứ hai nhỏ hơn fi rst; điều đó có nghĩa là không có sự chồng chéo.

1

Giả:

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). 

Chồng chéo hình chữ nhật RO tính như sau với C#:

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) = .... 

Nội hình chữ nhật RI:

Swap Min và Max trong dung dịch trên cho chồng chéo hình chữ nhật RO.

0

tôi đã sử dụng một validator trừu tượng cho dự án của tôi và để kiểm tra xem một số điều khiển bố trí nơi chồng chéo Tôi tạo ra hình chữ nhật ra trong những nhân vật bố trí:

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))); 
     } 
Các vấn đề liên quan