8

I have TikZ code that draws an ellipse. Here is the code that, AFAIK, draws the actual ellipse:

\draw [rotate around={0.:(0.,0.)},line width=0.8pt] (0.,0.) ellipse (5.cm and 4.cm);

Can anyone tell me how draw actually produces the line-work, i.e., is it behind-the-scenes using an interpolation algorithm to create coordinate points?

I've used Geogebra to generate TikZ code of a graph, and occasionally it simply brute-forces the shape of a line or object by generating tons of individual coordinates, making it rather unwieldy to put into a LaTeX document.

This, however, suggests to me the actual drawing of a shape with just a one-liner like above is some sort of interpolation, i.e. plotting per the ellipse formula a minimum base set of points, then interpolating the rest to fill in between them. I've read that this is typical, since using the ellipse formula to produce all of the points would be very resource and time expensive. Does anyone know what is going on under the hood?

  • 1
    If I recall correctly, one can not draw a "perfect" circle in a pdf. It is interpolated through spline curves and can be arbitrary precise (by increasing the number of splines). But one never gets a "perfect" circle/ellipse. – Willem Van Onsem May 7 at 13:33
9

As JouleV points out, the ellipse is drawn in four Bezier curves. If you do not want to look these things up in the code, you can always use show path construction to see how the path is constructed.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{decorations.pathreplacing}
\begin{document}
\begin{tikzpicture}[decoration={show path construction, % see p. 634 of the pgfmanual
    moveto code={
      \fill [red] (\tikzinputsegmentfirst) circle (2pt)
        node [fill=none, below] {moveto};},
    lineto code={
      \draw [blue,->] (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast)
        node [above] {lineto};
    },
    curveto code={
      \draw [green!75!black,->] (\tikzinputsegmentfirst) .. controls
        (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
        ..(\tikzinputsegmentlast) node [above] {curveto};
    },
    closepath code={
      \draw [orange,->] (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast)
        node [above] {closepath};}
}]
\draw [rotate around={0.:(0.,0.)},line width=0.8pt,postaction=decorate] (0.,0.) ellipse (5.cm and 4.cm);
\end{tikzpicture}
\end{document}

enter image description here

This is also true for circles, which is why rotating a circle can modify its bounding box.

8

pgfcorepathconstruct.code.tex, lines 892–1010:

% Append  an ellipse to the current path.
%
% #1 = center
% #2 = first axis
% #3 = second axis
%
% Example:
%
% % Add a circle of radius 3cm around the origin
% \pgfpathellipse{\pgforigin}{\pgfxy(2,0)}{\pgfxy(0,1)}
%
% % Draw a non-filled circle of radius 1cm around the point (1,1)
% \pgfpathellipse{\pgfxy(1,1)}{\pgfxy(1,1)}{\pgfxy(-2,2)}
% \pgfstroke

\def\pgfpathellipse#1#2#3{%
  \pgfpointtransformed{#1}% store center in xc/yc
  \pgf@xc=\pgf@x%
  \pgf@yc=\pgf@y%
  \pgfpointtransformed{#2}%
  \pgf@xa=\pgf@x% store first axis in xa/ya
  \pgf@ya=\pgf@y%
  \advance\pgf@xa by-\pgf@pt@x%
  \advance\pgf@ya by-\pgf@pt@y%
  \pgfpointtransformed{#3}%
  \pgf@xb=\pgf@x% store second axis in xb/yb
  \pgf@yb=\pgf@y%
  \advance\pgf@xb by-\pgf@pt@x%
  \advance\pgf@yb by-\pgf@pt@y%
  {%
    \advance\pgf@xa by\pgf@xc%
    \advance\pgf@ya by\pgf@yc%
    \pgf@nlt@moveto{\pgf@xa}{\pgf@ya}%
  }%
  \pgf@x=0.55228475\pgf@xb% first arc
  \pgf@y=0.55228475\pgf@yb%
  \advance\pgf@x by\pgf@xa%
  \advance\pgf@y by\pgf@ya%
  \advance\pgf@x by\pgf@xc%
  \advance\pgf@y by\pgf@yc%
  \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}%
  \pgf@x=0.55228475\pgf@xa%
  \pgf@y=0.55228475\pgf@ya%
  \advance\pgf@x by\pgf@xb%
  \advance\pgf@y by\pgf@yb%
  {%
    \advance\pgf@x by\pgf@xc%
    \advance\pgf@y by\pgf@yc%
    \advance\pgf@xb by\pgf@xc%
    \advance\pgf@yb by\pgf@yc%
    \pgf@temp%
    \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xb}{\pgf@yb}%
  }%
  \pgf@xa=-\pgf@xa% flip first axis
  \pgf@ya=-\pgf@ya%
  \pgf@x=0.55228475\pgf@xa% second arc
  \pgf@y=0.55228475\pgf@ya%
  \advance\pgf@x by\pgf@xb%
  \advance\pgf@y by\pgf@yb%
  \advance\pgf@x by\pgf@xc%
  \advance\pgf@y by\pgf@yc%
  \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}%
  \pgf@x=0.55228475\pgf@xb%
  \pgf@y=0.55228475\pgf@yb%
  \advance\pgf@x by\pgf@xa%
  \advance\pgf@y by\pgf@ya%
  {%
    \advance\pgf@x by\pgf@xc%
    \advance\pgf@y by\pgf@yc%
    \advance\pgf@xa by\pgf@xc%
    \advance\pgf@ya by\pgf@yc%
    \pgf@temp%
    \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xa}{\pgf@ya}%
  }%
  \pgf@xb=-\pgf@xb% flip second axis
  \pgf@yb=-\pgf@yb%
  \pgf@x=0.55228475\pgf@xb% third arc
  \pgf@y=0.55228475\pgf@yb%
  \advance\pgf@x by\pgf@xa%
  \advance\pgf@y by\pgf@ya%
  \advance\pgf@x by\pgf@xc%
  \advance\pgf@y by\pgf@yc%
  \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}%
  \pgf@x=0.55228475\pgf@xa%
  \pgf@y=0.55228475\pgf@ya%
  \advance\pgf@x by\pgf@xb%
  \advance\pgf@y by\pgf@yb%
  {%
    \advance\pgf@x by\pgf@xc%
    \advance\pgf@y by\pgf@yc%
    \advance\pgf@xb by\pgf@xc%
    \advance\pgf@yb by\pgf@yc%
    \pgf@temp%
    \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xb}{\pgf@yb}%
  }%
  \pgf@xa=-\pgf@xa% flip first axis once more
  \pgf@ya=-\pgf@ya%
  \pgf@x=0.55228475\pgf@xa% fourth arc
  \pgf@y=0.55228475\pgf@ya%
  \advance\pgf@x by\pgf@xb%
  \advance\pgf@y by\pgf@yb%
  \advance\pgf@x by\pgf@xc%
  \advance\pgf@y by\pgf@yc%
  \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}%
  \pgf@x=0.55228475\pgf@xb%
  \pgf@y=0.55228475\pgf@yb%
  \advance\pgf@x by\pgf@xa%
  \advance\pgf@y by\pgf@ya%
  {%
    \advance\pgf@x by\pgf@xc%
    \advance\pgf@y by\pgf@yc%
    \advance\pgf@xa by\pgf@xc%
    \advance\pgf@ya by\pgf@yc%
    \pgf@temp%
    \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xa}{\pgf@ya}%
  }%
  \pgf@nlt@closepath%
  \pgf@nlt@moveto{\pgf@xc}{\pgf@yc}%
}

Well, just by reading the comments there you will know that the ellipse is drawn by four different curves (each curve is drawn with a \pgf@nlt@curveto).

Note that the same happens with circle.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.