Столкнулся с интересным результатом при прорисовывании в QPainter квадратного изображения QPixmap с помощью функции drawPixmap. После поворота изображение уменьшалось. Результат представлен на рисунке.

Большой сектор нарисован без поворота, а маленький с поворотом.
Отображение осуществлялось с помощью следующего кода.
myPaiter.begin(Pm0);
myPaiter.drawPixmap(rect0, p0);
QPixmap p1 = p0.transformed(t0);
myPaiter.drawPixmap(rect0, p1);
myPaiter.end();
Причины уменьшения изображения после поворота объясняются ниже.
На рисунке слева изображён квадрат с вписанным в него кругом, имеющий размеры w0, w0. После поворота изображения его внешние размеры увеличиваются (средний рисунок) и становятся w1, w1. После приведения внешних размеров к исходному размеру диаметр вписанного в квадрат круга уменьшается (правая часть рисунка).

Чтобы сохранить пропорции отображаемого рисунка, необходимо в экземпляре QRect скомпенсировать размеры, оставив центр изображения на том же месте. Исходные размеры рисунка не будут искажены, если после поворота он будет отображаться на месте QRect(x0 - otst, y0 - otst, w1, w1), где: otst = (w1 - w0) / 2.
В данном случае следует определить во сколько увеличить размер w1 по отношению к размеру w0. Эта величина равна p1.width() / p0.width() (в соответствии с представленным выше кодом).
При отображении второго сектора с учётом увеличения получается следующий рисунок, на котором оба сектора одинакового размера. Назовём это компенсацией размеров по первому типу.

Код, с помощью которого осуществился вывод этого рисунка, следующий
myPaiter.begin(Pm1);
myPaiter.drawPixmap(rect0, p0);
int width0 = p0.width();
int width1 = p1.width();
int w1 = w0 * width1 / width0;
int otst = (w1 - w0) / 2;
QRect rectNew1(x0 - otst, y0 - otst, w1, w1);
myPaiter.drawPixmap(rectNew1, p1);
myPaiter.end();
Вполне логично будет рассмотреть (пусть это будет негромко сказано) математическую основу явления.
Изменение вторичных размеров (после поворота) носит повторяющийся характер. Размер полностью сохраняется при поворотах кратных 90 градусам. Минимальный размер будет при поворотах на угол 45 + n * 90 градусов. С учётом математики последовательность преобразований будет выглядеть следующим образом:
-
берётся модуль угла, на который проведен поворот ugAbs = fabs(ugRot);
-
рассчитывается остаток от деления на 90 градусов ost = fmod(ugAbs, 90.);
-
рассчитывается модуль отклонения остатка от 45 градусов mug = fabs(ost - 45.);
-
рассчитывается косинус этого угла cMug = cos(mug * M_PI / 180.);
-
рассчитывается косинус угла 45 градусов c45 = cos(45 * M_PI / 180.);
-
рассчитываются размеры отображаемого изображения w1 = w0 * cMug / c45;
-
рассчитывается смещение изображения otst = w0 * (cMug / c45 - 1.) / 2..
При компенсации размеров сектора с использованием представленных формул оба сектора на рисунке получились одинакового размера.

Код, с помощью которого осуществился вывод этого рисунка, следующий
myPaiter.begin(Pm2);
myPaiter.drawPixmap(rect0, p0);
qreal ugAbs = fabs(ugRot);
qreal ost = fmod(ugAbs, 90.);
qreal mug = fabs(ost - 45.);
qreal cMug = cos(mug * M_PI / 180.);
qreal c45 = cos(45. * M_PI / 180.);
w1 = w0 * cMug / c45;
otst = w0 * (cMug / c45 - 1.) / 2.;
QRect rect1(x0 - otst, y0 - otst, w1, w1);
myPaiter.drawPixmap(rect1, p1);
myPaiter.end();
На мой взгляд, первый вариант компенсации размеров рисунка выглядит наиболее предпочтительным.
Эксперименты проводились в программе, главная форма которой представлена на рисунке ниже.

Слева отобржение второго сектора без компенсации размеров. Посредине с компенсацией размеров по первому типу. Справа с компенсацией размеров из математических соображений.
Код создания этой формы следующий
#include "mainwindow.h"
#include <QFrame>
#include <QHBoxLayout>
#include <QPixmap>
#include <QLabel>
#include <QPainter>
#include <QRect>
#include <QtMath>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QFrame * F_Main = new QFrame;
QHBoxLayout * HBL_Main = new QHBoxLayout;
QPixmap * Pm0 = new QPixmap(400,400);
Pm0->fill();
QPainter myPaiter;
QPixmap p0 = QPixmap(":/resource/red_sect.svg");
int x0 = 50;
int y0 = 50;
int w0 = 300;
QRect rect0(x0, y0, w0, w0);
QTransform t0;
qreal ugRot = 45.;
t0.rotate(ugRot);
myPaiter.begin(Pm0);
myPaiter.drawPixmap(rect0, p0);
QPixmap p1 = p0.transformed(t0);
myPaiter.drawPixmap(rect0, p1);
myPaiter.end();
QLabel * L_0 = new QLabel;
L_0->setPixmap(*Pm0);
HBL_Main->addWidget(L_0);
HBL_Main->addSpacing(10);
QPixmap * Pm1 = new QPixmap(400,400);
Pm1->fill();
myPaiter.begin(Pm1);
myPaiter.drawPixmap(rect0, p0);
int width0 = p0.width();
int width1 = p1.width();
int w1 = w0 * width1 / width0;
int otst = (w1 - w0) / 2;
QRect rectNew1(x0 - otst, y0 - otst, w1, w1);
myPaiter.drawPixmap(rectNew1, p1);
myPaiter.end();
QLabel * L_1 = new QLabel;
L_1->setPixmap(*Pm1);
HBL_Main->addWidget(L_1);
HBL_Main->addSpacing(10);
QPixmap * Pm2 = new QPixmap(400,400);
Pm2->fill();
myPaiter.begin(Pm2);
myPaiter.drawPixmap(rect0, p0);
qreal ugAbs = fabs(ugRot);
qreal ost = fmod(ugAbs, 90.);
qreal mug = fabs(ost - 45.);
qreal cMug = cos(mug * M_PI / 180.);
qreal c45 = cos(45. * M_PI / 180.);
w1 = w0 * cMug / c45;
otst = w0 * (cMug / c45 - 1.) / 2.;
QRect rect1(x0 - otst, y0 - otst, w1, w1);
myPaiter.drawPixmap(rect1, p1);
myPaiter.end();
QLabel * L_2 = new QLabel;
L_2->setPixmap(*Pm2);
HBL_Main->addWidget(L_2);
F_Main->setLayout(HBL_Main);
setCentralWidget(F_Main);
}
MainWindow::~MainWindow() {
}
Автор: alex00s