PDA

View Full Version : Trouble drawing an arc exactly through two points



atsui
12th October 2012, 18:56
Hi,

I have two points that lie on a given circle and I would like to stroke the arc between these points. The way I'm doing this is to start a QPainterPath at one of the points and arcTo the other point. However, the resulting arc does not pass through the points as expected. It doesn't even lie on the same circle.

Here's an example. I've drawn black lines to the two points i would like an arc through.

8304

The arc is really small so it looks like there is only one black line, but we can zoom in to see the problem.

8305

The red line is the result of constructing the path as I described above. It moves exactly to one of the points, but as soon as it tries to start the arc, it finds that the starting point of the arc doesn't coincide with the path's current position and makes a jump. This is unexpected because I know the circle and the angles exactly.

So I tried to just draw the circle that I was given to begin with, seen in blue in the above screenshots. It looks like it neither passes through the points as it should, nor does it agree with the arc drawn from the QPainterPath.

Do you all have any feedback about what might be wrong? Is there any other way to achieve an arc through two points on a circle?

Here's some code that does everything above. You can pass some command line argument and it zoom in on the problem area.



#include <QtGui>

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QGraphicsScene scene;

double cx = -190.8327267606721;
double cy = 84.8432984839708;
double r = 208.8408841691493;
double theta = 0.41536317837389986;
double theta2 = 0.4148755982739018;

QPen bluePen( Qt::blue );
QPen redPen( Qt::red );

QGraphicsEllipseItem *item = new QGraphicsEllipseItem( 0, &scene );
QRectF circleBox( cx - r, cy - r, 2*r, 2*r );
item->setRect( circleBox );
item->setPen( bluePen );

QLineF l1 = QLineF::fromPolar( r, theta * 180/M_PI );
QLineF l2 = QLineF::fromPolar( r, theta2 * 180/M_PI );
l1.translate( cx, cy );
l2.translate( cx, cy );

QGraphicsLineItem *lineItem1 = new QGraphicsLineItem( 0, &scene );
QGraphicsLineItem *lineItem2 = new QGraphicsLineItem( 0, &scene );
lineItem1->setLine( l1 );
lineItem2->setLine( l2 );

QPainterPath path;
path.moveTo( l2.p2( ) );
path.arcTo( circleBox, theta2 * 180/M_PI, (theta - theta2) * 180/M_PI );
QGraphicsPathItem *arcItem = new QGraphicsPathItem;
arcItem->setPen( redPen );
arcItem->setPath( path );
scene.addItem( arcItem );

QGraphicsView view;
view.setScene( &scene );

if ( argc > 1 )
{
QPointF delta( 0.2, 0.2 );
view.fitInView( QRectF( l1.p2( ) - delta, l1.p2() + delta) );
}

view.show( );
return app.exec();
}


Thanks,