QGraphicsItem *GridLineFactory::ellipseItem (const Transformation &transformation, double radiusLinearCartesian, const QPointF &posStartScreen, const QPointF &posEndScreen) const { // LOG4CPP_INFO_S is below QPointF posStartGraph, posEndGraph; transformation.transformScreenToRawGraph (posStartScreen, posStartGraph); transformation.transformScreenToRawGraph (posEndScreen, posEndGraph); // Get the angles about the origin of the start and end points double angleStart = posStartGraph.x() * DEGREES_TO_RADIANS; double angleEnd = posEndGraph.x() * DEGREES_TO_RADIANS; if (angleEnd < angleStart) { angleEnd += TWO_PI; } double angleSpan = angleEnd - angleStart; // Get origin QPointF posOriginGraph (0, 0), posOriginScreen; transformation.transformLinearCartesianGraphToScreen (posOriginGraph, posOriginScreen); LOG4CPP_INFO_S ((*mainCat)) << "GridLineFactory::ellipseItem" << " radiusLinearCartesian=" << radiusLinearCartesian << " posStartScreen=" << QPointFToString (posStartScreen).toLatin1().data() << " posEndScreen=" << QPointFToString (posEndScreen).toLatin1().data() << " posOriginScreen=" << QPointFToString (posOriginScreen).toLatin1().data() << " angleStart=" << angleStart / DEGREES_TO_RADIANS << " angleEnd=" << angleEnd / DEGREES_TO_RADIANS << " transformation=" << transformation; // Compute rotate/shear transform that aligns linear cartesian graph coordinates with screen coordinates, and ellipse parameters. // Transform does not include scaling since that messes up the thickness of the drawn line, and does not include // translation since that is not important double ellipseXAxis, ellipseYAxis; QTransform transformAlign; createTransformAlign (transformation, radiusLinearCartesian, posOriginScreen, transformAlign, ellipseXAxis, ellipseYAxis); // Create a circle in graph space with the specified radius QRectF boundingRect (-1.0 * ellipseXAxis + posOriginScreen.x(), -1.0 * ellipseYAxis + posOriginScreen.y(), 2 * ellipseXAxis, 2 * ellipseYAxis); GraphicsArcItem *item = new GraphicsArcItem (boundingRect); item->setStartAngle (angleStart * RADIANS_TO_TICS); item->setSpanAngle (angleSpan * RADIANS_TO_TICS); item->setTransform (transformAlign.transposed ().inverted ()); return item; }