PDA

View Full Version : Best place to apply a QMatrix transform to paint() event in an app



Caolan O'Domhnaill
2nd October 2015, 21:24
Hello all,

I am working on a mathematics tutor app and so I need to transform my coordinate space into traditional Cartesian Coordinates.

I have found a solution here: http://stackoverflow.com/questions/4413570/use-window-viewport-to-flip-qpainter-y-axis

which I have added to one of my QGraphicsItem object's paint() event handlers for testing but I would like to apply it at a more global scale. I looked at the widget I am using as the QGraphicsView as the place to set this however it doesn't have a paint(), just these:

virtual void drawBackground(QPainter * painter, const QRectF & rect)
virtual void drawForeground(QPainter * painter, const QRectF & rect)

If I wanted to plug the code into my application so that EVERYTHING is drawn automagically in the coordinate system I need it to be, where is the best place to put it?

Code I have added to my QGraphicsItem:

void PhysVector::paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, QWidget *) {

// Setting the matrix rotates the drawing area to be a normal cartesian plane. Unfortunately
// it also means that the original drawing has to be tweaked
QMatrix matrix;
matrix.scale(1, -1);
pPainter -> setMatrix(matrix);

One further note I would like to make, is I would like to affect ONLY the drawing of objects, not the interaction of mouse clicks and what not. Unless they are inseparable I mean...
Thank you!
- Caolan

Kryzon
3rd October 2015, 00:10
Is something like QGraphicsView::setTransform (http://doc.qt.io/qt-5/qgraphicsview.html#setTransform) what you're looking for?

Caolan O'Domhnaill
3rd October 2015, 01:52
based ont he link you gave, it transforms to view coordinates which as I understand it only affect coordinates system with respect to World and local coordinates. It does not do any kind of flip of the y-axis like the QMatrix example I used above seems to do.

I could be wrong, I am new to this, however that is my interpretation.

Kryzon
3rd October 2015, 01:59
QTransform is a type of matrix that supports perspective transformations (including affine).
QMatrix only supports affine transformations (translation, rotation, shear and scale).

You can create a QTransform and use QTransform::scale( 1.0, -1.0 ) (to flip the vertical axis) and then assign it to the graphics view using setTransform.

Then consider your graphics scene as in cartesian coordinates: treat all coordinates as in a cartesian space. When displayed through the graphics view, the transform of the graphics view will convert from cartesian to device coordinates.

Caolan O'Domhnaill
5th October 2015, 18:55
GREAT! Thank you so very much!

-Caolan.

Caolan O'Domhnaill
6th October 2015, 20:26
Aaaaaaaand now everything in my view is upside down... *facepalm* :)

Kryzon
6th October 2015, 23:59
Here's a suggestion: translate that transform to the centre of the viewport. It should look more like a cartesian representation.

QPoint viewportCentre = viewport().rect().center();
QTransform::translate( viewportCentre.x(), viewportCentre.y() );

Make sure you are specifying coordinates in "cartesian" space: +X is to the right, +Y is up.

Caolan O'Domhnaill
13th October 2015, 19:49
Here's a suggestion: translate that transform to the centre of the viewport. It should look more like a cartesian representation.

QPoint viewportCentre = viewport().rect().center();
QTransform::translate( viewportCentre.x(), viewportCentre.y() );

Make sure you are specifying coordinates in "cartesian" space: +X is to the right, +Y is up.



I got it all to work. Thank you very much!