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;
}