# How can I draw this cone exactly?

I want to draw this cone, where SO = a, OA = 2a, AB=2a*sqrt(3). This is the picture which I draw in Geospacw.

With some calculates, we have AOB=120 degrees and H is midpoint of the segment SM.

This is my code

\documentclass[border=2mm,tikz]{standalone}
\usepackage{fouriernc}
\usepackage{tikz-3dplot}
\usetikzlibrary{calc,backgrounds}
\usepackage{tkz-euclide,amsmath}
\usetkzobj{all}
\usepackage{pgfplots}

\begin{document}

%polar coordinates of visibility
\pgfmathsetmacro\th{60}
\pgfmathsetmacro\az{110}
\tdplotsetmaincoords{\th}{\az}
%parameters of the cone
\pgfmathsetmacro\v{1.8} %hight of cone
\begin{tikzpicture} [scale=1.5, tdplot_main_coords, axis/.style={blue,thick}]
\path
coordinate (O) at (0,0,0)
coordinate (B) at (0,\R,0)
coordinate (A) at ($(O) + (-30:{\R} and {\R})$)
%coordinate (A) at (\R/2,0.8660254038*\R,0)
coordinate (S) at (0,0,\v)
coordinate (C) at  ($(O)-(A)$)
coordinate (M) at ($(A)!.5!(B)$)
coordinate (H) at ($(M)!1/2!(S)$)
;

\foreach \v/\position in { B/below,O/left,A/below,S/above,M/below,H/right} {\draw[draw =black, fill=black] (\v) circle (1pt) node [\position=0.2mm] {$\v$};
}

\draw[thick] (S) -- (A) (S) -- (B);
\draw[dashed] (A) -- (B) (S)--(O)  (O)--(A) (O) -- (M) (S) -- (M) (O)--(B) (O)--(H);
%\tkzMarkRightAngle[size = 0.15](S,O,A)
%\tkzMarkRightAngle[size = 0.15](S,M,A)
%\tkzMarkRightAngle[size = 0.15](O,M,B)
%\tkzMarkRightAngle[size = 0.15](O,H,M)

\tkzMarkSegment[color=black,pos=0.5,mark=||](A,M)
\tkzMarkSegment[color=black,pos=0.5,mark=||](B,M)

%\draw [fill opacity=0.4,fill=green!80!blue] (S) -- (A) -- (C) -- cycle;
% % computation of tangential points
\pgfmathsetmacro\cott{{cot(\th)}}
\pgfmathsetmacro\fraction{\R*\cott/\v}

\pgfmathsetmacro\fraction{\fraction<1 ? \fraction : 1}

\pgfmathsetmacro\angle{{acos(\fraction)}}

% % angles for transformed lines
\pgfmathsetmacro\PhiOne{180+(\az-90)+\angle}
\pgfmathsetmacro\PhiTwo{180+(\az-90)-\angle}

% % coordinates for transformed surface lines
\pgfmathsetmacro\sinPhiOne{{sin(\PhiOne)}}
\pgfmathsetmacro\cosPhiOne{{cos(\PhiOne)}}
\pgfmathsetmacro\sinPhiTwo{{sin(\PhiTwo)}}
\pgfmathsetmacro\cosPhiTwo{{cos(\PhiTwo)}}

% % angles for original surface lines
\pgfmathsetmacro\sinazp{{sin(\az-90)}}
\pgfmathsetmacro\cosazp{{cos(\az-90)}}
\pgfmathsetmacro\sinazm{{sin(90-\az)}}
\pgfmathsetmacro\cosazm{{cos(90-\az)}}

% % draw basis circle
\tdplotdrawarc[tdplot_main_coords,thick]{(O)}{\R}{\PhiOne}{360+\PhiTwo}{anchor=north}{}
\tdplotdrawarc[tdplot_main_coords,dashed,thick]{(O)}{\R}{\PhiTwo}{\PhiOne}{anchor=north}{}

% % displaying tranformed surface of the cone (rotated)
\draw[thick] (0,0,\v) -- (\R*\cosPhiOne,\R*\sinPhiOne,0);
\draw[thick] (0,0,\v) -- (\R*\cosPhiTwo,\R*\sinPhiTwo,0);

% % displaying original surface of the cone (rotated)

\end{tikzpicture}

\end{document}


My problem is: How to put OA = 2 OS or \R = 2\v?

• Uh, don't set \R=3 and \v=1.9. And since OA=\R and OS=\v... – John Kormylo Nov 6 '17 at 14:30
• @JohnKormylo Thank you for your Comment. I can't do it. – minhthien_2016 Nov 8 '17 at 15:57
• The problem is that S is now below the top of the arc, therefore no tangent lines are possible. You should probably change you viewing angle, or not attempt to draw tangents. – John Kormylo Nov 8 '17 at 22:23
• Quick fix: Add \pgfmathsetmacro\fraction{\fraction<1 ? \fraction : 1} after \fraction is computed and before \angle is computed. – John Kormylo Nov 8 '17 at 22:32
• @JohnKormylo It worked, but view not very good. – minhthien_2016 Nov 9 '17 at 7:22

Base on JohnKormylo'comment and use \pgfmathsetmacro\th{70}, I solved my problem.

\documentclass[border=2mm,tikz]{standalone}
\usepackage{fouriernc}
\usepackage{tikz-3dplot}
\usetikzlibrary{calc,backgrounds}
\usepackage{tkz-euclide,amsmath}
\usetkzobj{all}
\usepackage{pgfplots}
\begin{document}
%polar coordinates of visibility
\pgfmathsetmacro\th{70}
\pgfmathsetmacro\az{110}
\tdplotsetmaincoords{\th}{\az}
%parameters of the cone
\pgfmathsetmacro\v{2} %hight of cone
\begin{tikzpicture} [scale=1, tdplot_main_coords, axis/.style={blue,thick}]
\path
coordinate (O) at (0,0,0)
coordinate (B) at (0,\R,0)
coordinate (A) at ($(O) + (-30:{\R} and {\R})$)
%coordinate (A) at (\R/2,0.8660254038*\R,0)
coordinate (S) at (0,0,\v)
coordinate (C) at  ($(O)-(A)$)
coordinate (M) at ($(A)!.5!(B)$)
coordinate (H) at ($(M)!1/2!(S)$)
;
\foreach \v/\position in { B/below,O/left,A/below,S/above,M/below,H/right} {\draw[draw =black, fill=black] (\v) circle (1pt) node [\position=0.2mm] {$\v$};
}

\draw[thick] (S) -- (A) (S) -- (B);
\draw[dashed] (A) -- (B) (S)--(O)  (O)--(A) (O) -- (M) (S) -- (M) (O)--(B) (O)--(H);
\tkzMarkSegment[color=black,pos=0.5,mark=||](A,M)
\tkzMarkSegment[color=black,pos=0.5,mark=||](B,M)

%\draw [fill opacity=0.4,fill=green!80!blue] (S) -- (A) -- (C) -- cycle;
% % computation of tangential points
\pgfmathsetmacro\cott{{cot(\th)}}
\pgfmathsetmacro\fraction{\R*\cott/\v}

\pgfmathsetmacro\fraction{\fraction<1 ? \fraction : 1}

\pgfmathsetmacro\angle{{acos(\fraction)}}

% % angles for transformed lines
\pgfmathsetmacro\PhiOne{180+(\az-90)+\angle}
\pgfmathsetmacro\PhiTwo{180+(\az-90)-\angle}

% % coordinates for transformed surface lines
\pgfmathsetmacro\sinPhiOne{{sin(\PhiOne)}}
\pgfmathsetmacro\cosPhiOne{{cos(\PhiOne)}}
\pgfmathsetmacro\sinPhiTwo{{sin(\PhiTwo)}}
\pgfmathsetmacro\cosPhiTwo{{cos(\PhiTwo)}}

% % angles for original surface lines
\pgfmathsetmacro\sinazp{{sin(\az-90)}}
\pgfmathsetmacro\cosazp{{cos(\az-90)}}
\pgfmathsetmacro\sinazm{{sin(90-\az)}}
\pgfmathsetmacro\cosazm{{cos(90-\az)}}

% % draw basis circle
\tdplotdrawarc[tdplot_main_coords,thick]{(O)}{\R}{\PhiOne}{360+\PhiTwo}{anchor=north}{}
\tdplotdrawarc[tdplot_main_coords,dashed,thick]{(O)}{\R}{\PhiTwo}{\PhiOne}{anchor=north}{}

% % displaying tranformed surface of the cone (rotated)
\draw[thick] (0,0,\v) -- (\R*\cosPhiOne,\R*\sinPhiOne,0);
\draw[thick] (0,0,\v) -- (\R*\cosPhiTwo,\R*\sinPhiTwo,0);

% % displaying original surface of the cone (rotated)
\end{tikzpicture}
\end{document}


Here's a version in Metapost, showing one way to find the tangent points of an ellipse, following a traditional construction rather than calculating it with trigonometry. As usual with plain MP, this is "fake 3D" rather than a real three dimensional drawing.

\RequirePackage{luatex85}
\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}

% find one focus of an ellipse E:
% the intersection of (a circle with diameter = major axis shifted to the "top" of
% the ellipse) and (the major axis)

vardef focus(expr E) =
fullcircle scaled abs(point 0 of E-point 4 of E) shifted point 2 of E
intersectionpoint
(point 0 of E -- point 4 of E)
enddef;

% find the "time" round an ellipse E of the first tangent point
% to the external point P.  Will fail if P is inside E.
% See http://wiki.dtonline.org/index.php/Tangents_and_Normals for details.

vardef tangent_time(expr E, P) =
save f;
pair f, f';
f = focus(E);
f' = f reflectedabout(point 2 of E, point 6 of E);
xpart (E intersectiontimes (f' --
(fullcircle scaled 2 abs(P-f) shifted P intersectionpoint
fullcircle scaled 2 abs(point 4 of E - point 0 of E) shifted f')))
enddef;

% decorate a path P with N slightly oblique marks at point R of P

vardef mark_along(expr P, R, N) =
for i=1 upto N:
draw (down--up) scaled 3 rotated -5 shifted (i-N/2,0)
rotated angle direction R of P shifted point R of P;
endfor
enddef;

beginfig(1);

% an ellipse
path base;
base = fullcircle xscaled 233 yscaled 144;

% some pairs
pair A, B, S, O, M, H;
O = origin;
A = point 5.1 of base;
B = point 7.9 of base;
S = 144 up;
M = 1/2[A,B];
H = 1/2[S,M];

% the two tangent "times" along base
numeric t, u;
t = tangent_time(base, S);
u = 4-t;

% draw some dashed lines
drawoptions(dashed evenly scaled 1/2);
draw subpath (t,u) of base withcolor 1/2 white;
draw A--O--B--cycle;
draw S--O--M--cycle;
draw O--H;

% mark equality
drawoptions(withcolor 2/3 red);
mark_along(A--M, 1/2, 2);
mark_along(M--B, 1/2, 2);

% draw some solid lines
drawoptions();
draw S -- subpath (u,8+t) of base -- cycle;
draw A--S--B;

% label the points
dotlabel.ulft("O", O);
dotlabel.llft("A", A);
dotlabel.lrt ("B", B);
dotlabel.lrt ("M", M);
dotlabel.urt ("H", H);
dotlabel.top ("S", S);

endfig;
\end{mplibcode}
\end{document}


This is wrapped up in luamplib so compile with lualatex, or adapt for plain MP, etc.

## Notes

• The constructions are from this useful site.

• There are 8 points around my ellipse here because I inherit them from fullcircle.

• The normal way to make an ellipse in MP is to use the fullcircle path and stretch it to the major axis with xscaled and to the minor axis with yscaled.

• The focus function assumes that you have arranged your ellipse like this so that the major axis runs from point 0 to point 4 and the minor axis runs from point 2 to point 6.

• The focus function only returns one of the focus points. The other one will be symmetrical about the minor axis.

• The tangent_time function returns the time along the ellipse path of the point of the first tangent to the external point. The other tangent will be symmetrical about the line from the centre of the ellipse to the external point. Here I know the external point is directly above, so I can cheat and get the second point with u=4-t.

• Notice the two different MP commands intersectionpoint and intersectiontimes. Section 9.2 of the manual explains more about them.