I want rotate a QGraphicsPixmapItem around a point according to mouse position.
So i tried this:
void Game::mouseMoveEvent(QMouseEvent* e){
setMouseTracking(true);
QPoint midPos((sceneRect().width() / 2), 0), currPos;
currPos = QPoint(mapToScene(e->pos()).x(), mapToScene(e->pos()).y());
QPoint itemPos((midPos.x() - cannon->scenePos().x()), (midPos.y() - cannon->scenePos().y()));
double angle = atan2(currPos.y(), midPos.x()) - atan2(midPos.y(), currPos.x());
cannon->setTransformOriginPoint(itemPos);
cannon->setRotation(angle); }
But the pixmap moves a few of pixels.
CodePudding user response:
Besides the mixup of degrees and radians that @rafix07 pointed out there is a bug in the angle calculation. You basically need the angle of the line from midPos
to currPos
which you calculate by
double angle = atan2(currPos.y() - midPos.y(), currPos.x() - midPos.x());
Additionally the calculation of the transformation origin assumes the wrong coordinate system. The origin must be given in the coordinate system of the item in question (see QGraphicsItem::setTransformOriginPoint), not in scene coordinates. Since you want to rotate around the center of that item it would just be:
QPointF itemPos(cannon->boundingRect().center());
Then there is the question whether midPos
is actually the point highlighted in your image in the middle of the canon. The y-coordinate is set to 0 which would normally be the edge of the screen, but your coordinate system may be different.
I would assume the itemPos
calculated above is just the right point, you only need to map it to scene coordinates (cannon->mapToScene(itemPos)
).
Lastly I would strongly advise against rounding scene coordinates (which are double
s) to int
s as it is done in the code by forcing it to QPoint
s instead of QPointF
s. Just use QPointF
whenever you are dealing with scene coordinates.