PDA

View Full Version : setTransformOriginPoint



brianc
16th August 2010, 22:25
Can someone please help me figure out how setTransformationOriginPoint works?

I have a simple program where I am trying to rotate an image using the image edges as the rotation axis. If you press the up arrow, it should rotate along the top axis. The bottom arrow should rotate along the bottom axis, etc.

Of course, that's not what happens. For each case, it appears that the rotation axis is 0,0. Can someone please show my what I'm doing wrong, or let me know if there is a better way to rotate images along different axis.


#include "mainwindow.h"

#include <QGraphicsScene>
#include <QHBoxLayout>
#include <QGraphicsView>
#include <QKeyEvent>

MainWindow::MainWindow(QWidget *parent)
: QWidget(parent)
{

QGraphicsScene *scene = new QGraphicsScene();
scene->setSceneRect(-150, -150, 300, 300);
scene->setBackgroundBrush(Qt::white);

item = new QGraphicsPixmapItem(QPixmap(":/images/0.png"));
item->setPos(QPointF(-item->boundingRect().width()/2,-item->boundingRect().height()/2));
scene->addItem(item);


QGraphicsView *view = new QGraphicsView();
view->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
view->setScene(scene);
view->setSceneRect(-150, -150, 300, 300);
view->setFocus();

QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(view);
setLayout(layout);

rotateTimeLine = new QTimeLine(1500, this);
rotateTimeLine->setCurveShape(QTimeLine::LinearCurve);

connect(rotateTimeLine, SIGNAL(valueChanged(qreal)),
this, SLOT(updateRotate(qreal)));

}

MainWindow::~MainWindow()
{

}


void MainWindow::keyPressEvent(QKeyEvent *event)
{
qDebug("MainWindow::keyPressEvent");

switch (event->key()) {

case Qt::Key_Up:
rotate(0);
break;

case Qt::Key_Right:
rotate(1);
break;

case Qt::Key_Left:
rotate(2);
break;

case Qt::Key_Down:
rotate(3);
break;

}
}

void MainWindow::rotate(int axis)
{
rotateAxis = axis;
rotateAngle = 0;
rotateTimeLine->start();

}

void MainWindow::updateRotate(qreal value)
{
QTransform txf = QTransform();

rotateAngle = 360*value;

switch (rotateAxis)
{
case 0:
// Up arrow - Rotate along top axis
txf.rotate(rotateAngle, Qt::XAxis);
item->setTransformOriginPoint(item->boundingRect().width()/2, item->boundingRect().height()/2);
break;

case 1:
// Right arrow - Rotate along rigth axis
txf.rotate(rotateAngle, Qt::YAxis);
item->setTransformOriginPoint(item->boundingRect().width(), item->boundingRect().height()/2);
break;

case 2:
// Left arrow - Rotate along left axis
txf.rotate(rotateAngle, Qt::YAxis);
item->setTransformOriginPoint(0, item->boundingRect().height()/2);
break;

case 3:
// Down arrow - Rotate along bottom axis
txf.rotate(rotateAngle, Qt::XAxis);
item->setTransformOriginPoint(item->boundingRect().width()/2,item->boundingRect().height());
break;
}

item->setTransform(txf, false);
update();
}

Urthas
16th August 2010, 23:06
Well, your updateRotate logic isn't doing what you think it's doing. By analogy, you are pushing a thumb tack into a piece of construction paper on a cork board, and then rotating the paper around the tack.

I understand what you *want* to do, but not really how to do it. However, perhaps you should check out the HelloGL example, ignoring the gl-related code and concentrating on the rotation code. Worth a shot?

brianc
17th August 2010, 00:26
I have a work around now. I can get the behavior I'm looking for if I do the following:

* Translate the item to the rotation center point
* Rotate the item
* Translate the item back to the starting position

See the code below for details. I still don't understand why setTransformOriginPoint() doesn't work. Can any Qt experts out there shed some light on this.

Brian



void MainWindow::updateRotate(qreal value)
{
QTransform txf = QTransform();

rotateAngle = 360*value;

switch (rotateAxis)
{
case 0:
// Up arrow - Rotate along top axis
txf.translate(item->boundingRect().width()/2, 0);
txf.rotate(rotateAngle, Qt::XAxis);
txf.translate(-item->boundingRect().width()/2, 0);
//item->setTransformOriginPoint(item->boundingRect().width()/2, item->boundingRect().height()/2);
break;

case 1:
// Right arrow - Rotate along rigth axis
txf.translate(item->boundingRect().width(), item->boundingRect().height()/2);
txf.rotate(rotateAngle, Qt::YAxis);
txf.translate(-item->boundingRect().width(), -item->boundingRect().height()/2);
//item->setTransformOriginPoint(item->boundingRect().width(), item->boundingRect().height()/2);
break;

case 2:
// Left arrow - Rotate along left axis
txf.translate(0, item->boundingRect().height()/2);
txf.rotate(rotateAngle, Qt::YAxis);
txf.translate(0, -item->boundingRect().height()/2);
//item->setTransformOriginPoint(0, item->boundingRect().height()/2);
break;

case 3:
// Down arrow - Rotate along bottom axis
txf.translate(item->boundingRect().width()/2,item->boundingRect().height());
txf.rotate(rotateAngle, Qt::XAxis);
txf.translate(-item->boundingRect().width()/2,-item->boundingRect().height());
//item->setTransformOriginPoint(item->boundingRect().width()/2,item->boundingRect().height());
break;
}

item->setTransform(txf, false);
}