1 Ellipses

1.1 Ellipse Start and End Angles

An ellipical arc given by the center point \((cx,cy)\) and the two radius vectors \((r_1dx, r_1dy)\) and \((r_2dx, r_2dy)\) and the start angle \(\phi_1\) and end angle \(\phi_2\) is the set of all points \((x,y)\) which are on the ellipses, that is

\[ \begin{pmatrix}x \\ y \end{pmatrix} = \begin{pmatrix} r_1dx & r_1dy \\ r_2dx & r_2dy \end{pmatrix} \begin{pmatrix} x' \\ y' \end{pmatrix} + \begin{pmatrix} c_x \\ c_y \end{pmatrix} \mbox{, such that} \left|\begin{pmatrix}x' \\ y'\end{pmatrix}\right| = 1 \]

holds and whose angle relative to the center \((cx,cy)\) lies within the given range:

\[ \exists k \in \mathbb{N}, t \in [0,1]: \mbox{atan2}(y-c_y,x-c_x) = \phi_1 + t(\phi_2-\phi_1) + 2k\pi \]

For a [filled] ellipse this is the same, but \(\le 1\) instead of \(1\) above.

The consequence is that angles are measured in the user coordinate space and not in the coordinate space of a unit circle which needs to be transformed into the user coordinate space to get a given ellipse. This is in contrast with X11, which has its angles skewed by the same skewing applied to a circle to get the ellipse.

Further angles are measured in the usual mathematical sense. Whether positive angles appear counter-clockwise or clockwise depends on the coordinate space. CLIM mediums have their default x-axis pointing right and the y-axis pointing down, the consequence of which is that as angles increase you move clockwise on the physical medium the figure is rendered to.

1.1.1 Direction

When rendering a curve direction does matter. The direction also matters when constructing pathes from curves.

Also, elliptical arcs are always swept out beginning at the start angle and ending at the end angle. If the end angle is numerically larger than the start angle angles increase while travelling the curve. This is counter-clockwise in a Cartesian coordinate space and clockwise on a typical CLIM medium with the y-axis pointing down.

When the end angle is numerically less than the start angle, sweeping the curve still starts at the start angle but decreases as it approaches the end angle. Moving clockwise in Cartesian coordinates and counter-clockwise in a coordinate system with a flipped y-axis.

A dash pattern starts at the start angle.

If the start and end angle are equal, the elliptical arc or the ellipse (pie slice) is empty and when drawn no pixels are affected.

If the difference between the start angle and end angle is \(2\pi\) or larger a full ellipse is specified. Even if the difference is larger, no pixel is rendered twice.

1.1.2 Illustration

To illustrate we show an elliptical arc as constructed by

(make-elliptical-arc* 0 0 -120 -30 80 -60
                      :start-angle (* 1/6 pi)
                      :end-angle (* 3/4 pi))

or the "pie slice" as constructed by

(make-ellipse* 0 0 -120 -30 80 -60 :start-angle (* 1/6 pi) :end-angle (* 3/4 pi))

Note that the coordinate system is a "first quardrant" coordinate system with the y-axis pointing up.

X Y (r1dx,r1dy) (r2dx,r2dy) (cx,cy) φ 1 = 30° φ 2 = 135°

Elliptical arc and pie slice swept out by start angle $\phi_1$ and end angle $\phi_2$

2 Survey

We summarize how different other graphics APIs handle arcs and ellipses.

PostScript

PostScript has an arc and an arcn operator which take a center point, a radius and start/end angles. Angles are interpreted modulo 2π. arc always runs counter-clockwise in user coordinate space, arcn always runs clockwise.

All arcs are circular, there are no ellipses.

cx cy r angle1 angle2 arc
cx cy r angle1 angle2 arcn

With angle2 < angle1 nothing is drawn.

PDF

PDF has no ellipical arc operators.

Cairo

Cairo is the same as PostScript. It has

cairo_arc (cr, cx, cy, r, angle1, angle2)
cairo_arc_negative (cr, cx, cy, r, angle1, angle2)
Quartz

The CGContextAddArc operation has an explicit clockwise flag and in this regard is essentially like PostScript.

There also is CGContextAddArcToPoint which is like the arct PostScript operator.

CGContextAddArc (gc, xc, yc, start, end, clockwise);
CGContextAddArcToPoint (gc, x1, y1, x2, y2, r);
X11

The PolyArc X11 request can only draw axis-aligned ellipses, angles are skewed and arcs always run clockwise with regard to Cartesian coordinates, counter-clockwise on screen.

That is angles are measured at a unit circle which then is unevenly scaled to inscribe the rectangle given.

xlib:draw-arc drawable gcontext x y width height angle1 angle2

Dashing starts at angle1. If angle2 < angle1 nothing is drawn.

GDI+

The documentation of the DrawArc operation with GDI+ does not say anything about how angles are to be interpreted, the signature looks like X11:

DrawArc (pen, x, y, w, h, startAngle, sweepAngle);

However, angles are interpreted in user coordinate space with the usual mathematical orientation. Arcs are counter-clockwise with positive sweepAngle arguments and clockwise with negative sweepAngle arguments.

Dashing always starts at startAngle.