Then we can just pick a new place for that center point, and transform that back into a non-overlapping position for the original rectangle. This lets us resolve the collision in one pass, touching the x coordinate only once and thex or y coordinate, and only once - rather than stacking a vertical collision resolution after a horizontal resolution using outdated info.
We call this the "minimum translation vector" - using the smallest adjustment possible to remove the overlap, whether that's horizontal or vertical.
if(first.Bounds.IntersectsWith(second.Bounds) == false) return; // Compute the center of each rectangle: var firstCenter = new PointF( first.Left + first.Width /2f, first.Top + first.Height /2f ); var secondCenter = new PointF(second.Left + second.Width /2f, second.Top + second.Height/2f); // Compute the offset from the second's center to the first. var offset = firstCenter - secondCenter; // ClampCompute thishow offsetdeeply towe're theoverlapping, closesthorizontally pointand onvertically. var thepenetration enlarged= new PointF((first.Width + second /.Width )/2f, rectangle's perimeter. First horizontally. (first.Height - second.Height)/2f); if - new PointF(Math.Abs(offset.x), <Math.Abs(offset.y)); if (first penetration.Widthy +<= second0 || (penetration.Widthx > 0 && penetration.x < penetration.y)/2f) { // If we're only overlapping on the x, // or we're overlapping on the x less than on the y, // then correct our x position for the minimum safe correction. offset.x = Math.Sign(offset.x) * (first.Width + second.Width )/2f; } else { // ...thenOtherwise, vertically. ifour (Math.Abs(offset.y)minimum <safe (first.Heightcorrection +is secondvertical.Height)/2f) offset.y = Math.Sign(offset.y) * (first.Height + second.Height)/2f);2f; } // Now form the top-left corner of the first rectangle at // this new position. var corner = new PointF(secondCenter.x + offset.x - first.Width /2f, secondCenter.y + offset.y - first.Height/2f); first.SetPosition(corner);