Contrary to images, when we want to rotate a polygon (a rectangle in this case) around its center, we have to use a transformation like
T = translate(center).rotate(r).translate(-center)
(remember transformations are applied from right to left). Scaling is discarded for the moment. For images such initial translation is implicit.
The issue in this case is that the image changes its dimensions after rotating: the size of the new image is the bounding rectangle that contains the rotated pixels, thus the last translate is no longer valid for your case (the translate(center)
).
Instead, you need something like:
T = translate(new_rect.size() / 2).rotate(r).translate(-original_center)
To achieve this, you have to split the transformation in two parts (scaling brought back too):
T1 = rotate(r).scale(s, s).translate(-center)
T2 = translate(new_rect.size() / 2)
since the new rect size can only be computed after applying the first transformation.
Also, see that for T2
I'm not talking about the center but the half size, because the new center will not express the same meaning for images than for polygon (images don't have negative pixel coordinate, for example)
Expressed using Qt API:
// Image transformation
auto transform = QTransform().rotateRadians(r).scale(s, s);
auto image = m_image.transformed(transform, Qt::SmoothTransformation);
// Assuming something like: QPainter painter(this);
painter.drawImage(0, 0, image);
// Rect to polygon
const auto rect = m_image.rect();
QPolygonF pol;
pol << rect.topLeft();
pol << rect.topRight();
pol << rect.bottomRight();
pol << rect.bottomLeft();
// First transformation
const auto center = rect.center();
transform = transform.translate(-center.x(), -center.y());
const auto pol2 = transform.map(pol);
// Second transformation
const auto rect2 = pol2.boundingRect();
painter.drawPolygon(QTransform().translate(rect2.width() / 2, rect2.height() / 2).map(pol2));
Full code available in GitHub.