# Drawing ellipses with pict2e or the like

\usepackage{pict2e}

\usepackage{pstricks-add}

\usepackage{pst-node,pst-plot}

\psset{plotpoints=9,unit=3}


Somehow, acting on various people's advice, I've put the above lines of code above my \begin{document} line, and I'm not sure what the difference is between the contents of the three packages nor what that last command does but I've been able to draw some simple diagrams that I needed, involving lines and dots and circles and text at certain places.

Now I'd like to draw an ellipse. I can specify the endpoints of the major and minor axes, and those are horizontal and vertical rather than at some odd angle, and I can also specify four points in a symmetrical pattern on the curve.

Can that be done?

-
Line 2, 3 and 4 are relevant to the pstricks bundle, completely different from the pict2e package (and much more powerful). To have a more precise idea about the drawing solutions related to LaTeX, may I recommend this topic from the TeX FAQ: tex.ac.uk/cgi-bin/texfaq2html?label=drawing –  Franck Pastor Mar 25 '14 at 19:35
Thank you to all who replied. I may try these today or tomorrow in the paper I'm writing. –  Michael Hardy Mar 27 '14 at 18:28

## 6 Answers

With pstricks, quite easily:

        \documentclass[a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\pagestyle{empty}

\usepackage[pdf, svgnames]{pstricks}%
\usepackage{pstricks-add}

\begin{document}

\begin{pspicture}
\psaxes{->}(0,0)(-6,-5)(7,5)
\psclip{
\psellipse[linewidth = 1.5pt, linecolor = Purple](1,-1)(4,3)}
\psset{linestyle = dashed, linewidth = 0.6pt}
\psline(1,-5)(1,7)\psline(-6,-1)(7,-1)
\endpsclip
\psEllipseTangents(1,-1)(4,3)(-2,3)
\psline{*-*}(-2,3)(EllipseT1)
\psline{*-*}(-2,3)(EllipseT2)
\end{pspicture}

\end{document}


Explanation: \psellipse has the coordinates of its centre for first argument. The second argument gives its horizontal and its vertical semi-axes. To have ans ellipse with other axes, you have to rotate it around its centre.

As for the psEllipseTangent macro, it allows to draw the tangent lines to an ellipse from a given point; it has the coordinates of this point as a third argument. The points of contact with the ellipse are nodes named EllipseT1 and EllipseT2.

-
I'm not sure that adding the MinionPro package in examples is a good idea; I believe it's preferable to keep the package at the bare minimum necessary for producing the example. –  egreg Mar 25 '14 at 22:31
Sorry! I took a file of mine for it already had a preamble loading pstricks & friends, and I forgot to check that point. I'll delete the corresponding line — for the image I think it's unimportant to load another with the "true" labels on the axes. –  Bernard Mar 25 '14 at 22:49
Thanks; it was just a precaution. We know what that package does, but a newbie could be mistaken. –  egreg Mar 25 '14 at 22:52

With tikz

\documentclass[svgnames,tikz,border=10pt]{standalone}
\begin{document}
\begin{tikzpicture}
\draw[very thick, -stealth] (-6,0) -- (6,0);
\foreach \x in {-5,-4,-3,-2,-1,1,2,3,4,5}{
\draw (\x,0.2) -- (\x,-0.2) node[below] {\x};
}
\draw[very thick, -stealth] (0,-6) -- (0,6);
\foreach \y in {-5,-4,-3,-2,-1,1,2,3,4,5}{
\draw (0.2,\y) -- (-0.2,\y) node[left] {\y};
}
\draw[very thick,Purple] (-1,3) arc [start angle=0,end angle=360,x radius = 2cm, y radius=1cm]node[circle,fill,pos=0.3,sloped,inner sep=2pt] (a){} node [circle,fill,pos=0.9,sloped,inner sep=2pt] (b) {};
\draw[shorten <= -1cm, shorten >= -7cm] (a.west) -- (a.east);
\draw[shorten <= -1cm, shorten >= -5cm] (b.west) -- (b.east);
\end{tikzpicture}
\end{document}


-
+1 Great example of lateral thinking! I always struggle to draw tangents with TikZ. –  Pier Paolo Mar 28 '14 at 22:38

A similar solution but with fewer packages loaded:

\documentclass{article}

\usepackage{pstricks-add}

\begin{document}

\begin{pspicture}(-4.2,-2.2)(4.85,5.7)
\psaxes{->}(0,0)(-4.2,-2.2)(4.5,5.3)[$x$,0][$y$,90]
\psdot(2,4)
\psellipse(0,0)(3,1.5)
\psEllipseTangents(0,0)(3,1.5)(2,4)
\psset{nodesep = -1cm, linecolor = blue}
\pcline(2,4)(EllipseT1)
\pcline(2,4)(EllipseT2)
\psdots(EllipseT1)(EllipseT2)
\uput[135](EllipseT1){$T_{1}$}
\uput[45](EllipseT2){$T_{2}$}
\end{pspicture}

\end{document}


-
I had to load pstricks and pstricks-add because, strangely, it's impossible to load pstricks-add with pdf option. I really wonder why since it loads pstricks. –  Bernard Mar 25 '14 at 22:54

An Asymptote solution, that exploits a simpler case of unitcircle as a basis to get the tangential points to the ellipse. The procedure getTangentPoints calculates two tangent points using two input parameters: transform tr, which is used to transform a unitcircle at the origin into the ellipse, and a pair T - coordinates of the point.

%
% ell.tex :
%
\documentclass[10pt,a4paper]{article}
\usepackage{lmodern}
\usepackage{subcaption}
\usepackage[inline]{asymptote}
\begin{asydef}
import graph;
import fontsize;
defaultpen(fontsize(9pt));

pair O=(0,0);

pen linepen=deepblue+0.8bp;
pen tanpen=orange+0.8bp;
pen graypen=gray+0.6bp;

pair[] getTangentPoints(transform tr, pair T){
assert(!inside(tr*Circle(O,1),T)
,"*** The point is not outside of the ellipse ***");
pair[] p=new pair[2];
pair tmp1, tmp2;
transform tphi;
tmp1=tr^(-1)*T;
tphi=rotate(-degrees(dir(tmp1)));
tmp2=tphi*tmp1;
p[0]=(1/tmp2.x,sqrt(1-1/tmp2.x^2));
p[1]=(p[0].x,-p[0].y);
return tr*tphi^(-1)*p;
}
\end{asydef}
\usepackage[left=2cm,right=2cm,top=2cm,bottom=2cm]{geometry}
%
\begin{document}
%
\begin{figure}
\captionsetup[subfigure]{justification=centering}
\centering
\begin{subfigure}{0.45\textwidth}
\begin{asy}
size(70mm);
real a=2, b=0.618a;

pair T0=(1.5,-2);

transform tr=shift(1.3,-0.5)*rotate(20)*scale(a,b);
guide Ellipse=tr*Circle(O,1);

pair[] T=getTangentPoints(tr,T0);

xaxis(RightTicks(OmitTick(0),Step=1,step=0.5));
yaxis( LeftTicks(OmitTick(0),Step=1,step=0.5));

draw(Ellipse,linepen);
draw(tr*(N--S),graypen);draw(tr*(E--W),graypen);
draw(T0--(T[0]+dir(T[0]-T0)),tanpen);
draw(T0--(T[1]+dir(T[1]-T0)),tanpen);

dot(T0--T[0]--tr*O--T[1],UnFill);

label("$T_0$",T0,T0-tr*O);
label("$T_1$",T[0],T[0]-tr*O);
label("$T_2$",T[1],T[1]-tr*O);

\end{asy}
%
\caption{}
\label{fig:1a}
\end{subfigure}
%
\begin{subfigure}{0.45\textwidth}
\begin{asy}
size(70mm);
real a=3, b=0.2a;

pair T0=(4,0.9);

transform tr=shift(0.3,-1.5)*rotate(-35)*scale(a,b);
guide Ellipse=tr*Circle(O,1);

pair[] T=getTangentPoints(tr,T0);

xaxis(RightTicks(OmitTick(0),Step=1,step=0.5));
yaxis( LeftTicks(OmitTick(0),Step=1,step=0.5));

draw(Ellipse,linepen);
draw(tr*(N--S),graypen);draw(tr*(E--W),graypen);
draw(T0--(T[0]+dir(T[0]-T0)),tanpen);
draw(T0--(T[1]+dir(T[1]-T0)),tanpen);

dot(T0--T[0]--tr*O--T[1],UnFill);

label("$T_0$",T0,T0-tr*O);
label("$T_1$",T[0],T[0]-tr*O);
label("$T_2$",T[1],T[1]-tr*O);
\end{asy}
%
\caption{}
\label{fig:1b}
\end{subfigure}
\caption{}
\label{fig:1}
\end{figure}
%
\end{document}
%
% Process:
%
% pdflatex ell.tex
% asy ell-*.asy
% pdflatex ell.tex

-

A simple solution, using my package xpicture:

\documentclass{standalone}
\usepackage{xpicture}

\begin{document}

\setlength{\unitlength}{1cm}
\begin{Picture}(-8,-8)(8,8)

\cartesiangrid(-7,-7)(7,7)

\pictcolor{blue}\Ellipse{2}{3}
\pictcolor{red}\Put(3,4){\Ellipse{4}{2}}
\pictcolor{green}\Put(-3.5,0){\Ellipse{3.5}{7}}

\referencesystem(4,-4)(1,1)(1,-1)
\pictcolor{magenta}\Ellipse{1}{2}
\end{Picture}

\end{document}


-
I'm trying to figure out how to download this. I go t the linked page and it says "xpicture homepage", and I click on "Downloading and using xpicture". I get a page that says "Download xpicture", and I click on "Download xpicture". Then I'm looking at ctan.org/tex-archive/macros/latex/contrib/calculator . This seems to be about a different package. I can download files with the extensions .dtx, .ins, and .pdf . –  Michael Hardy Apr 2 '14 at 23:35
Ooops! Thank you, Michael. The correct link is ctan.org/tex-archive/macros/latex/contrib/xpicture. I've corrected. –  Robert Fuster Apr 4 '14 at 6:49

A MetaPost example. Much lengthier than it could have been, because I couldn't resist the very attractive challenge of creating macro(s) for drawing the tangents to an ellipse from a given point: unlike for PStricks, these macros are not part of standard MetaPost. Fortunately, programming in MetaPost is easy once you've learned the basics.

I've tried to make clear below in the comments what code is necessary for the ellipse itself and what is needed for the labels or for the tangents.

EDIT I forgot: it is to be typeset with the numbersystem flag set to double (floating-point arithmetic allows more precision for the computations about tangents):

mpost --numbersystem=double file.mp

EDIT 2: I've improved my code, by borrowing some nice ideas of g.kow's Asymptote program below, such as considering the affine transformation defining the ellipse as a parameter. However, I've kept the horizontal and vertical axes, according to the OP's wishes. Now the code makes use of the MetaFun format and must be typeset as such:

mpost --numbersystem=double --mem=metafun file.mp

% LaTeXMP: Package for much better management of LaTeX labels in MetaPost
input latexmp; setupLaTeXMP(options="12pt", textextlabel=enable, mode=rerun);

u := cm; % unit length;

% Macro returning the points M of fullcircle
% (fullcircle is the unit circle — diameter 1bp - centered at origin)
% such that (IM) is tangent to fullcircle
vardef tangent_points_of_fullcircle(expr I)(suffix M) =
save intersect, circle; pair intersect; path circle;
circle = fullcircle scaled (abs I) shifted .5I;
intersect = circle intersectiontimes fullcircle;
if intersect <> (-1, -1):
M1 = circle intersectionpoint fullcircle; M2 = M1 reflectedabout(origin, I);
fi;
enddef;

% Macro returning the points N of an ellipse of center C and semi-axes a and b
% such that (IN) is tangent to the ellipse
% Adapts the preceeding macro through the affine transform T
vardef tangent_points_of_ellipse(expr I, T)(suffix N) =
save J, M; pair J, M[];
J = I transformed inverse T;
if abs(J) <= 0.5: N1 = I;
else:
tangent_points_of_fullcircle(J)(M);
for i=1, 2:
N[i] = M[i] transformed T;
endfor;
fi;
enddef;

% Draw the straight line through points A and B and beyond them
% (thus more than the segment [AB])
vardef straight_line(expr A, B) =
A + 1.25*unitvector(A-B) -- B + 1.25*unitvector(B-A)
enddef;

% The figure itself
beginfig(1);

% drawing the ellipse of center z0 and semi-axes a and b
z0 = (2, 1); a := 4; b := 3;
transform T; T = identity xyscaled 2(a, b) shifted z0;
draw fullcircle transformed T scaled u withcolor red;

% labelling the ellipse and its parameters
draw ((x0-a, y0) -- (x0+a, y0)) scaled u dashed evenly;
draw ((x0, y0-b) -- (x0, y0+b)) scaled u dashed evenly;
label.llft("$z_0$", z0*u);
label.bot("$a$", u*0.5[z0, z0+(a, 0)]);
label.lft("$b$", u*0.5[z0, z0+(0, b)]);

% Axes and labels
xmin := -5 + x0 ; xmax := 5 + x0; ymin := -4+y0; ymax := 4.5+y0;
drawarrow ((xmin, 0) -- (xmax, 0)) scaled u;
drawarrow ((0, ymin) -- (0, ymax)) scaled u;
label.llft("$O$", origin); label.bot("$x$", (xmax*u, 0)); label.lft("$y$", (0, ymax*u));

% The tangents
pair I, N[]; I = (5, 4.3);
tangent_points_of_ellipse(I, T)(N);
if N1<>I:
for i = 1, 2:
draw straight_line(I, N[i]) scaled u withcolor blue;
draw u*N[i] withpen pencircle scaled 3bp;
endfor;
freedotlabel("$I$", I*u, z0);
else:
picture error_message;
error_message = thefreelabel("Outside the ellipse, please!", I*u, z0);
unfill bbox error_message;
draw I*u withpen pencircle scaled 3bp; draw error_message;
fi;

endfig;
end.


-