4

1. Goal

My colleague and I have been trying to render rotated ellipsoids in Qt. The typical solution approach, as we understand it, consists of shifting the center of the ellipsoids to the origin of the coordinate system, doing the rotation there, and shifting back: http://qt-project.org/doc/qt-4.8/qml-rotation.html

2. Sample Code

Based on the solution outlined in the link above, we came up with the following sample code:

// Constructs and destructors
RIEllipse(QRect rect, RIShape* parent, bool isFilled = false)
: RIShape(parent, isFilled), _rect(rect), _angle(30)
{}

// Main functionality
virtual Status draw(QPainter& painter)
{
   const QPen& prevPen = painter.pen();  
   painter.setPen(getContColor());
   const QBrush& prevBrush = painter.brush();
   painter.setBrush(getFillBrush(Qt::SolidPattern));

   // Get rectangle center
   QPoint center = _rect.center();

   // Center the ellipse at the origin (0,0)
   painter.translate(-center.x(), -center.y());
   // Rotate the ellipse around its center
   painter.rotate(_angle);
   // Move the rotated ellipse back to its initial location
   painter.translate(center.x(), center.y());

   // Draw the ellipse rotated around its center
   painter.drawEllipse(_rect);

   painter.setBrush(prevBrush);
   painter.setPen(prevPen);
   return IL_SUCCESS;
}

As you can see, we have hard coded the rotation angle to 30 degrees in this test sample.

3. Observations

The ellipses come out at wrong positions, oftentimes outside the canvas area.

4. Question

What is wrong about the sample code above?

Best regards,

Baldur

P.S. Thanks in advance for any constructive response?

P.P.S. Prior to posting this message, we searched around quite a bit on stackoverflow.com. Qt image move/rotation seemed to reflect a solution approach similar to the link above.

Community
  • 1
  • 1
user2514673
  • 109
  • 1
  • 7
  • 1
    I think that the `translate` function works opposite to how you think. Try negating the values you are passing in. – paddy Jun 24 '13 at 02:18

2 Answers2

0

In painter.translate(center.x(), center.y()); you shift your object by the amount of current coordinate which makes (2*center.x(), 2*center.y()) as a result. You may need:

painter.translate(- center.x(), - center.y()); 
fatihk
  • 7,789
  • 1
  • 26
  • 48
0

The theory of moving an object back to its origin, rotating and then replacing the object's position is correct. However, the code you've presented is not translating and rotating the object at all, but translating and rotating the painter. In the example question that you've referred to, they're wanting to rotate the whole image about an object, which is why they move the painter to the object's centre before rotating.

The easiest way to do rotations about a GraphicsItem is to initially define the item with its centre in the centre of the object, rather than in its top left corner. That way, any rotation will automatically be about the objects centre, without any need to translate the object.

To do this, you'd define the item with a bounding rect for x,y,width,height with (-width/2, -height/2, width, height).

Alternatively, assuming your item is inherited from QGraphicsItem or QGraphicsObject, you can use the function setTransformOriginPoint before any rotation.

Community
  • 1
  • 1
TheDarkKnight
  • 27,181
  • 6
  • 55
  • 85
  • No problem, let us know how you get on. Also, for performance you should try to avoid doing anything other than rendering in the paint functions. Of-course, if you actually did want to rotate the whole image, then you'd need to do it there, as that's where you get the painter object. – TheDarkKnight Jun 24 '13 at 14:42