@@ -258,14 +258,52 @@ def draw(
258258 painter .setRenderHint (QG .QPainter .Antialiasing )
259259 painter .setPen (pen )
260260 painter .setBrush (brush )
261+
262+ # Draw the axes lines connecting handles
261263 painter .drawLine (line0 )
262264 painter .drawLine (line1 )
263- painter .save ()
264- painter .translate (rect .center ())
265- painter .rotate (- line0 .angle ())
266- painter .translate (- rect .center ())
267- painter .drawEllipse (rect .toRect ())
268- painter .restore ()
265+
266+ # For the ellipse, we need to handle non-uniform aspect ratios properly.
267+ # The ellipse should have its semi-axes aligned with line0 and line1 directions.
268+ # We use QPainterPath to draw an ellipse transformed to match the actual
269+ # geometry.
270+ center = line0 .pointAt (0.5 )
271+
272+ # Create the ellipse in a local coordinate system where line0 is horizontal
273+ # and line1 is vertical, then transform it to match the actual geometry
274+ path = QG .QPainterPath ()
275+
276+ # Calculate the angle between line0 and line1 in pixel space
277+ # (they should be 90° in data space but may differ after transformation)
278+ angle0 = math .radians (line0 .angle ())
279+ angle1 = math .radians (line1 .angle ())
280+
281+ # Semi-axes lengths
282+ a = line0 .length () / 2 # semi-major axis (along line0)
283+ b = line1 .length () / 2 # semi-minor axis (along line1)
284+
285+ # Draw ellipse using parametric form, accounting for non-perpendicular axes
286+ # We sample points around the ellipse and create a path
287+ n_points = 72 # Number of points for smooth ellipse
288+ first_point = True
289+ for i in range (n_points + 1 ):
290+ t = 2 * math .pi * i / n_points
291+ # Parametric ellipse with potentially non-perpendicular axes
292+ # Point = center + cos(t) * a * dir0 + sin(t) * b * dir1
293+ dx = math .cos (t ) * a * math .cos (angle0 ) + math .sin (t ) * b * math .cos (angle1 )
294+ dy = - math .cos (t ) * a * math .sin (angle0 ) - math .sin (t ) * b * math .sin (
295+ angle1
296+ )
297+ px = center .x () + dx
298+ py = center .y () + dy
299+ if first_point :
300+ path .moveTo (px , py )
301+ first_point = False
302+ else :
303+ path .lineTo (px , py )
304+ path .closeSubpath ()
305+ painter .drawPath (path )
306+
269307 if symbol != QwtSymbol .NoSymbol :
270308 for i in range (points .size ()):
271309 symbol .drawSymbol (painter , points [i ].toPoint ())
0 commit comments