2017-05-17 5 views
3

J'ai les cas suivants où les rectangles se chevauchent. enter image description hereDécalage des positions rectangle pour éviter le chevauchement

J'ai les coordonnées pour le rectangle d'intersection (bleu). Comment puis-je compenser les coordonnées de départ (XY en haut à gauche) des 2 rectangles pour éviter les chevauchements, à condition que i ont les coordonnées du rectangle d'intersection en utilisant

rectangle3 = Rectangle.Intersect(rectangle1, rectangle2); 

UPDATE:

Selon Mise à jour de @MBo i ont ajouté le code suivant

Blue = Rectangle.Intersect(First, Second); 
if (Blue != Rectangle.Empty) 
{ 
if (First.Right == Blue.Right) 
{ 

imgpoint.X += (Blue.Right - Blue.Left); 
} 

if (First.Bottom == Blue.Bottom) 
{ 
imgpoint.Y += (Blue.Bottom - Blue.Top); 
} 

if (First.Left == Blue.Left) 
{ 
imgpoint.X-= (Blue.Right - Blue.Left); 
} 
if (First.Top == Blue.Top) 
{ 
imgpoint.Y -= (Blue.Bottom - Blue.Top); 
} 
} 

MAJ2:

Conformément à la logique de @MBo j'ai mis en place le code ci-dessus.Cela fonctionne dans la plupart des cas.Mais dans certaines images, même lorsque l'intection est détectée et le décalage est ajouté, je me chevauche.Voir l'image ci-dessous.

Le problème réel que je suis en train de résoudre est liée à ces 2 questions Translating a Point(X,Y) for Images of Different Sizes from a Custom PictureBox Control

Performing Overlap Detection of 2 Bitmaps

conseils S'il vous plaît.

MISE À JOUR:enter image description here

MISE À JOUR:

Selon votre mise à jour je traduis le code Delphi à C#

Blue = Rectangle.Intersect(First, Second); 
if (Blue != Rectangle.Empty) 
{ 
int dcy,dcx; 
int dy,dx; 
int fl=First.Left,fw=First.Width,fh=First.Height,ft=First.Top,fb=First.Bottom,fr=First.Right; 
int sl=Second.Left,sr=Second.Right,st=Second.Top,sb=Second.Bottom,sw=Second.Width,sh=Second.Height; 
dcy = (sb + st) - (fb + ft); //doubled center y-difference 
dcx = (sl + sr) - (fl + fr); 
if ((int)(dcx) >= (fw + sw) || ((int)(dcy) >= (fh + sh))) 
{//no intersection 

} 
else 
{ 

dx = fw + sw - (int)dcx; //doubled needed x-shift absolute value 
dy = fh + sh - (int)dcy; 

if (dx > dy) 
{ 
if (dcy < 0) 
{ 
dy = - dy/2; 
} 
else 
{ 
dy = dy/ 2; //needed y-shift accounting for direction 
} 
dx = 0; 
} 
else 
{ 
if (dcy < 0) 
{ 
dx = - dx/ 2; 
} 
else 
{ 
dx = dx/2; 
dy = 0; 
} 
} 
imgpoint.X+=dx; 
imgpoint.Y+=dy; 
} 
} 

En utilisant ce code, la deuxième image est déplacé trop loin Dans certains cas.S'il vous plaît laissez-moi savoir si le code est correct.

enter image description here

+0

Vous utilisez '(int) (DCX)' et DCY en deux endroits où la valeur absolue est nécessaire (quelque chose comme 'math.abs') – MBo

+0

@MBo Thanks.Will vérifier et revenir. – techno

+0

@MBo Merci beaucoup :) Votre deuxième mise à jour fonctionne très bien après l'utilisation de 'Math.Abs'.Vraiment apprécier l'effort. – techno

Répondre

1

Edit: vérifié tous les cas possibles, avait obtenu le code suivant simple (code Delphi, fonctionne).

//fl, fw, fr, ft, fh, fb: First.Left, Width, Right, Top, Height, Bottom 
//s* - similar parameters for the second rectangle 


dcy := (sb + st) - (fb + ft); //doubled center y-difference 
dcx := (sl + sr) - (fl + fr); 
if (Abs(dcx) >= fw + sw) or ((Abs(dcy) >= fh + sh)) then //no intersection 
    Exit; 

dx := fw + sw - Abs(dcx); //doubled needed x-shift absolute value 
dy := fh + sh - Abs(dcy); 

if dx > dy then begin 
    if dcy < 0 then 
     dy := - dy div 2 
    else 
     dy := dy div 2; //needed y-shift accounting for direction 
    dx := 0; 
end else begin 
    if dcy < 0 then 
     dx := - dx div 2 
    else 
     dx := dx div 2; 
    dy := 0; 
end; 

//Result: dx, dy pair to shift the second rectangle 

Full code


Vieille réponse pour référence temporaire:

Vous avez besoin d'informations - ce que coordonnées du premier rectangle coïncide avec coordonnée correspondante du rectangle d'intersection. Pour les cas simples d'intersection:

case 
    First.Right = Blue.Right: 
     shift Second.Left by (Blue.Right - Blue.Left) 
    First.Bottom = Blue.Bottom: 
     shift Second.Top by (Blue.Bottom - Blue.Top) 
    First.Left = Blue.Left: 
     shift Second.Left by -(Blue.Right - Blue.Left) 
    First.Top = Blue.Top: 
     shift Second.Top by -(Blue.Bottom - Blue.Top) 

Edit:
Si l'intersection existe et aucun des cas ci-dessus est satisfaite, l'inclusion complète et l'intersection de croix a lieu.Donc, déterminer quel est le chemin le plus court pour éviter les chevauchements:

dcy = (Second.Bottom + Second.Top) - (First.Bottom + First.Top) 
if dcy >=0 then 
     shift Second.Top by (First.Bottom - Second.Top) //down 
else 
     shift Second.Top by -(Second.Bottom - First.Top) //up 

dcx = (Second.Left + Second.Right) - (First.Left + First.Right) 
if dcx >=0 then 
     shift Second.Left by (First.Right - Second.Left) //right 
else 
     shift Second.Left by -(Second.Right - First.Left) //left 
+0

Merci .. mais que se passe-t-il si 'Blue' a deux bords d'intersection ..? – techno

+0

et qu'en est-il de 'shift' gauche/droite? – techno

+0

Cela fonctionne pour le cas du coin-coin (deux conditions). À propos de cas plus complexes (croix etc) - vous avez écrit "j'ai les cas suivants". Shift left est fourni avec le signe moins here' - (Blue.Right - Blue.Left) ' – MBo

0

Vous devez vérifier si le r2 (rectangle2) si, entre R2.x et R2.x + r2.Height ou entre r2.Y et r2.Y + r2.Y + r2.Width ou non betwwen nous et apporter des changements je writed un exemple de code

private int GetNewX(Rectangle r1, Rectangle r2) 
{ 
    if (r2.X < r1.X) 
    { 
     return r1.X - r2.Width; 
    } 
    else 
    { 
     return r1.X + r1.Width; 
    } 
} 
private int GetNewY(Rectangle r1, Rectangle r2) 
{ 
    if (r2.Y < r1.Y) 
    { 
     return r1.Y - r2.Height; 
    } 
    else 
    { 
     return r1.Y + r1.Height; 
    } 
} 

Pen pen = new Pen(Color.Black); 
Rectangle r1 = new Rectangle(60, 10, 200, 200); 
Rectangle r2 = new Rectangle(40, 25, 200, 160); 


//If overlapped change X,Y of the r2 rectangle 
Rectangle overlapRect = Rectangle.Intersect(r1, r2); 
if (overlapRect.Width > 0 || overlapRect.Height > 0) 
{ 
    bool betweenX = overlapRect.X >= r1.X && overlapRect.X <= (r1.X + r1.Height); 
    bool betweenY = overlapRect.Y >= r1.Y && overlapRect.Y <= (r1.Y + r1.Width); 

    if (betweenX) 
    { 
     r2.X = GetNewX(r1,r2);      
    } 
    else if (betweenY) 
    { 
     r2.Y = GetNewY(r1, r2); 
    } 
    else 
    { 
     if (overlapRect.Width <= overlapRect.Height) 
     { 
      r2.X = GetNewX(r1, r2); 
     } 
     else 
     { 
      r2.Y = GetNewY(r1, r2); 
     } 
    }     
} 

Graphics g = this.CreateGraphics(); 
g.DrawRectangle(pen, r1); 
g.DrawRectangle(pen, r2); 
+0

Merci .. va essayer et revenir ... – techno

+0

vous êtes les bienvenus @techno. S'il vous plaît revenez si vous avez un problème. S'il vous plaît noter que j'ai utilisé mon code sur un formulaire –

+0

fera.thanks :). Voulez-vous dire que vous avez testé le code sur votre formulaire ... – techno