基于左上角缩放旋转的项目移动项目 [英] Scaling a rotated item based on top left moves the item

查看:60
本文介绍了基于左上角缩放旋转的项目移动项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够基于其中心旋转 QGraphicsItem,并基于左上角缩放它.

I would like to be able to rotate a QGraphicsItem based on its center, and scale it based on the top left corner.

当我尝试结合旋转和缩放时,该项目显然也在移动...

When I try to combine rotation and scaling, the item also apparently moves...

#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();
}

结果:

  • 绿色是旋转的,没有缩放(或缩放不同的量)
  • 黄色是缩放的,而不是旋转的
  • 蓝色按边界矩形的中心进行缩放和旋转(未调整大小)
  • 红色围绕中心缩放和旋转

现在对我来说很明显转换操作正确 - 如果我调整和旋转项目的大小,我首先得到黄色然后是红色项目.

It is evident now to me that the transformations operate correctly - if I resize and rotate an item, I get first the yellow then the red item.

然而,我需要的是,如果一个项目已经旋转(绿色)然后缩放,表现得像蓝色 - 在同一方向拉伸,不跳跃,而如果一个项目先缩放,然后旋转,表现就像红色...更复杂的是,原始项目(绿色)可能已经应用了缩放,所以我使用边界矩形的简单解决方案不起作用.

Yet, what I need, is if an item is already rotated (green) then scaled, to behave like the blue - stretch in the same direction, without jumping, while if an item is first scaled, then rotated, to behave like the red... Even more complicated, the original item (green) may have had scaling applied, so my simple solution of using the bounding rectangle wouldn't work.

我试图计算变化......总是得到奇怪的结果.

I have tried to calculate the change... Always with weird results.

是否可以基于左上角缩放旋转的项目,同时不移动它,同时还围绕其中心旋转?

Is it possible to scale a rotated item, based on top left, without also moving it, while also rotating it around its center ?

它可能需要增量转换,并且根据它们的应用顺序获得不同的结果会很奇怪.

It may require incremental transformations, and would be odd to get different results based on the order they are applied.

由于转换失败,我一直在尝试位置调整,但我无法获得转换函数的公式,该公式将为我提供平滑的视觉转换类型:

I have been experimenting with position adjustments, since the transformations have failed, but I have not been able to get a formula for a transform function that will give me smooth visual transition of the type:

1) 旋转项目(固定到中心)
2)缩放项目(固定在左上角)而不跳跃
3)旋转项目(固定到中心)

1) rotate item (pinned to center)
2) scale item (pinned to top left) without jumping
3) rotate item (pinned to center)

其中第 2 步还将包括位置偏移.我只是不知道该怎么做.
按照我的看法,在红色"变换的片段中,我会在变换前后添加 mapToScene(somePoint),并执行更正 (moveBy) 基于结果.

where step 2 would also include an offset in position. I just don't know how to do it.
The way I see it, in the fragment for the "red" transform, I would have o add a mapToScene(somePoint) before and after the transform, and perform a correction (moveBy) based on result.

这不是一个很好的修复,但仍然......如果我知道如何在调整大小后调整项目的位置使其不会跳跃,它仍然是一个修复......

This would not be a great fix, but still... If only I knew how to adjust the position of the item after resize so it doesn't jump, it would still be a fix...

推荐答案

这是我解决问题的尝试 - 它有效,但不是一个很好的解决方案:

This is my attempt to solve the problem - it works but it is not a great solution:

  • 在任何转换中,我都会存储 m31()m32().
  • 如果转换是缩放,我会通过新旧 m31()m32()
  • 之间的变化来抵消
  • on any transformation, I store m31() and m32().
  • If transformation is scaling, I offset by change between old and new m31() and m32()

这篇关于基于左上角缩放旋转的项目移动项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆