2010-07-03 8 views
7

Supongamos que tengo los siguientes rectángulos superpuestos ("a" y "b"):rectángulo Cómo conseguir la superposición de las coordenadas

aaaaaaaa 
aaaaccccbbbbb 
aaaaccccbbbbb 
aaaaccccbbbbb 
    bbbbbbbbb 
    bbbbbbbbb 

que he visto un montón de ideas sobre cómo calcular el área de de la rectángulo interno ("c"), pero ¿cómo podría obtener las coordenadas reales arriba/izquierda/abajo/derecha para ello?

Respuesta

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

El código anterior supone que los rectángulos no se cruzan. – ChrisW

+0

... siempre que el sistema de coordenadas tenga las direcciones positiva y hacia abajo como positivas. –

+0

@ChrisW: para comprobar si se cruzan: en todos los casos donde NO se cruzan, se cruzan. No se cruzan si StartA> EndB (a completamente después de B) o EndA Not A And Not B ==> (StartA <= EndB) y (EndA> = StartB), en cualquier otro caso, devuelve el rectángulo (0,0,0,0) o NULO. –

9

Las coordenadas X del área de superposición de dos rectángulos se pueden encontrar de acuerdo con la siguiente lógica.

Para encontrar las coordenadas Y, sustituya Y por X en el último de los cuatro supuestos, así como en los tres casos.


Supuestos:

  • A y B son rectángulos (con sus lados alineados a lo largo de la ejes X e Y),

  • cada uno de los rectángulos es definido por dos puntos   (x min/y min) – (x max/y max)

  • donde x min < x max   y   y min < y max  .

  • A.x min < B.x min


Caso 1 — No se junta:

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

A.x min < A.x max < B.x min < B.x max   ⇒   No solapamiento.


Caso 2 — Algunos solapamiento:

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

A.x min < B.x min < A.x máximo < B.x máximo   ⇒   superposición coordenadas X: B.x minA.x máximo


Caso 3 — solapamiento completo:

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

A.x min < B.x min < B.x max < A.x max   ⇒   Overlap coordenadas X: B.x minB.x max


P.S .: En realidad se puede simplificar aún más este algoritmo. Las coordenadas superposición X son siempre:

max (Ax min, Bx min) – min (Ax max, Bx max)

excepto cuando el segundo valor es menor que el fi primero; eso significa que no hay superposición.

1

Supongamos:

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

superposición rectángulo RO calcula como sigue con 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) = .... 

interior RI rectángulo:

Intercambio de Min y Max en solución anteriormente para la superposición de rectángulo RO.

0

que utiliza un validador abstracto para mi proyecto y para comprobar si algunos controles de diseño, donde se superponen que crean rectángulos fuera de las cifras de Presentación:

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))); 
     } 
Cuestiones relacionadas