Search code examples
c#.netwinformssystem.drawing

Determining Center point of a Rectangle and move New Rectangle to the Center


I have a rectangular selection made programatically on an Image.The user is provided the option to set the size of the rectangle,on doing so the rectangle size should increase but the center point of the old rectangle should be maintained,so that the contents within the rectangle is not out of focus.

Is this a correct approach

objSmall.X = CInt(objBig.X + (Math.Round(((objBig.Width / 2) - (objSmall.Width / 2)), 0)))
objSmall.Y = CInt(objBig.Y + (Math.Round(((objBig.Height / 2) - (objSmall.Height / 2)), 0)))

The new rectangle can be larger or smaller than the old one.


Solution

  • The calculation is correct; it can be simplified using just one integer division:
    (and translated to C#, because the source code is VB.Net)

    An integer division (MSDN Docs) can be used because we're dividing by 2, it's like rounding down. But you should use floating point values (float) when drawing, especially moving objects (with values expressed in both degrees and, of course, radians): your positions will be off quite a bit if you don't.

    objSmall.X = objBig.X + (objBig.Width - objSmall.Width) / 2;
    objSmall.Y = objBig.Y + (objBig.Height - objSmall.Height) / 2;
    

    Or (2):

    objSmall.Location = new Point(objBig.X + (objBig.Width - objSmall.Width) / 2,
                                  objBig.Y + (objBig.Height - objSmall.Height) / 2);
    

    Or, using the relative Centre coordinates of the larger object:

    Point BigRectCenter = new Point((objBig.Width / 2) + objBig.X, (objBig.Height / 2) + objBig.Y);
    
    objSmall.Location = new Point(BigRectCenter.X - (objSmall.Width / 2),
                                  BigRectCenter.Y - (objSmall.Height / 2));
    

    The (2) method can be also used when you don't know which one of the Rectangles is the largest.
    Assume you know your reference Rectangle's Location and Size and you let the User specify the new Size of the selection:

    Rectangle OriginalRect = new Rectangle(30, 30, 120, 90);
    Rectangle ResizedRect = new Rectangle(0, 0, 140, 140);
    

    The ResizedRect has a Size (defined by the User) but its Location is unknown at this point.
    The new selection Rectangle's (ResizedRect) Location can be calculated with:

    ResizedRect.Location = new Point(OriginalRect.X + (OriginalRect.Width - ResizedRect.Width) / 2,
                                     OriginalRect.Y + (OriginalRect.Height - ResizedRect.Height) / 2);
    

    Original Selection (Green)                    Original Selection (Green)
        (20, 20, 120, 120)                           (30, 30, 120,  90)
     Resized Selection (Red)                       Resized Selection (Red) 
        ( 0,  0,  95,  86)                           ( 0,  0, 140, 140)
    
      Calculated Selection                          Calculated Selection
           Rectangle                                      Rectangle
        (32, 37,  95,  86)                           (20, 5, 140, 140)
    

    Rectangle Selection