Определить центральную точку прямоугольника и переместить новый прямоугольник в центр

У меня есть прямоугольное выделение, сделанное программно на изображении. Пользователю предоставляется возможность установить размер прямоугольника, при этом размер прямоугольника должен увеличиваться, но центральная точка старого прямоугольника должна сохраняться, чтобы содержимое внутри прямоугольник не в фокусе.

Это правильный подход

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

Новый прямоугольник может быть больше или меньше старого.

1 ответ

Решение

Расчет верен; это можно упростить, используя только одно целочисленное деление:
(и переведено на C# потому что исходный код VB.Net)

Можно использовать разделение между числами ( Документы MSDN), потому что мы делим на 2, это как округление вниз. Но вы должны использовать значения с плавающей запятой (float) при рисовании, особенно движущихся объектов (со значениями, выраженными как в градусах, так и, конечно, в радианах): ваши позиции будут совсем немного отличаться, если вы этого не сделаете.

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

Или же (2):

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

Или, используя относительные координаты центра более крупного объекта:

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

(2) Метод также можно использовать, когда вы не знаете, какой из прямоугольников самый большой.
Предположим, вы знаете вашу ссылку Rectangle's Location а также Size и вы позволяете пользователю указать новый размер выделения:

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

ResizedRect имеет Size (определяется пользователем), но его Location на данный момент неизвестно.
Новый выбор Rectangle's (ResizedRect) Location можно рассчитать с помощью:

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)

Другие вопросы по тегам