【发布时间】:2015-11-28 03:45:18
【问题描述】:
我希望能够基于QGraphicsItem 的中心旋转它,并根据左上角对其进行缩放。
当我尝试结合旋转和缩放时,项目显然也移动了......
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsTextItem>
void testTransformations(QGraphicsScene* s)
{
qreal angle = 30, scaleX = 2, scaleY = 1;
// Reference rotated not scaled
QGraphicsTextItem* ref = new QGraphicsTextItem("bye world");
ref->setFont(QFont("Arial", 20));
ref->setDefaultTextColor(Qt::green);
s->addItem(ref);
qreal center0X = ref->boundingRect().center().x();
qreal center0Y = ref->boundingRect().center().y();
QTransform t0;
t0.translate(center0X, center0Y);
t0.rotate(angle);
t0.translate(-center0X, -center0Y);
ref->setTransform(t0);
// Reference scaled not rotated
QGraphicsTextItem* ref1 = new QGraphicsTextItem("bye world");
ref1->setFont(QFont("Arial", 20));
ref1->setDefaultTextColor(Qt::yellow);
s->addItem(ref1);
QTransform t;
t.scale(scaleX, scaleY);
ref1->setTransform(t);
// Rotate around center of resized item
QGraphicsTextItem* yyy = new QGraphicsTextItem("bye world");
yyy->setDefaultTextColor(Qt::red);
yyy->setFont(QFont("Arial", 20));
s->addItem(yyy);
qreal center1X = yyy->boundingRect().center().x() * scaleX;
qreal center1Y = yyy->boundingRect().center().y() * scaleY;
// in my code I store the item size, either before or after the resize, and use it to determine the center - which is virtually the same thing as this for a single operation
QTransform t1;
t1.translate(center1X, center1Y);
t1.rotate(angle);
t1.translate(-center1X, -center1Y);
t1.scale(scaleX, scaleY);
yyy->setTransform(t1);
// rotated around center of bounding rectangle
QGraphicsTextItem* xxx = new QGraphicsTextItem("bye world");
xxx->setDefaultTextColor(Qt::blue);
xxx->setFont(QFont("Arial", 20));
s->addItem(xxx);
qreal center2X = xxx->boundingRect().center().x();
qreal center2Y = xxx->boundingRect().center().y();
QTransform t2;
t2.translate(center2X, center2Y);
t2.rotate(angle);
t2.translate(-center2X, -center2Y);
t2.scale(scaleX, scaleY);
xxx->setTransform(t2);
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QGraphicsScene s;
QGraphicsView view(&s);
s.setSceneRect(-20, -20, 500, 500);
view.show();
testTransformations(&s);
return app.exec();
}
结果:
- 绿色旋转,未缩放(或缩放不同的量)
- 黄色是缩放的,不是旋转的
- 蓝色按边界矩形的中心进行缩放和旋转(未调整大小)
- 红色围绕中心缩放和旋转
现在对我来说很明显,转换操作正确 - 如果我调整和旋转一个项目,我首先得到黄色项目,然后是红色项目。
然而,我需要的是,如果一个项目已经旋转(绿色)然后缩放,表现得像蓝色 - 在同一方向拉伸,没有跳跃,而如果一个项目先缩放,然后旋转,表现像红色...更复杂的是,原始项目(绿色)可能已经应用了缩放,所以我使用边界矩形的简单解决方案不起作用。
我试图计算变化......总是得到奇怪的结果。
是否可以根据左上角缩放旋转的项目,而不移动它,同时围绕其中心旋转它?
这可能需要增量转换,并且根据应用的顺序得到不同的结果会很奇怪。
编辑:我一直在尝试调整位置,因为转换失败了,但我无法获得一个转换函数的公式,它可以让我平滑地看到类型的视觉转换:
1) 旋转项目(固定到中心)
2) 在不跳跃的情况下缩放项目(固定在左上角)
3)旋转项目(固定到中心)
其中步骤 2 还包括位置偏移。我只是不知道该怎么做。
在我看来,在“红色”变换的片段中,我将在变换前后添加一个mapToScene(somePoint),并根据结果执行校正(moveBy)。
这不是一个很好的修复,但仍然......如果我知道如何在调整大小后调整项目的位置使其不会跳跃,它仍然是一个修复......
【问题讨论】:
标签: qt rotation transform scaling qgraphicsitem