# Drawing conic projection with TikZ

I struggle with drawing a sphere that has a cone set on top of it. What I'm trying to get is something like this:

The left cone touches the sphere on one latitude and the right one intersects the surface of the sphere on two latitudes. Is this possible with TikZ?

Here is as far as how i got, it's basically this TikZ example: http://www.texample.net/tikz/examples/map-projections/

\documentclass{article}
\usepackage{tikz}

\newcommand\pgfmathsinandcos[3]{%
\pgfmathsetmacro#1{sin(#3)}%
\pgfmathsetmacro#2{cos(#3)}%
}
\newcommand\LongitudePlane[3][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{#2} % elevation
\pgfmathsinandcos\sint\cost{#3} % azimuth
\tikzset{#1/.estyle={cm={\cost,\sint*\sinEl,0,\cosEl,(0,0)}}}
}
\newcommand\LatitudePlane[3][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{#2} % elevation
\pgfmathsinandcos\sint\cost{#3} % latitude
\pgfmathsetmacro\yshift{\cosEl*\sint}
\tikzset{#1/.estyle={cm={\cost,0,0,\cost*\sinEl,(0,\yshift)}}} %
}
\newcommand\DrawLongitudeCircle[2][1]{
\LongitudePlane{\angEl}{#2}
\tikzset{current plane/.prefix style={scale=#1}}
% angle of "visibility"
\pgfmathsetmacro\angVis{atan(sin(#2)*cos(\angEl)/sin(\angEl))} %
\draw[current plane] (\angVis:1) arc (\angVis:\angVis+180:1);
\draw[current plane,dashed] (\angVis-180:1) arc (\angVis-180:\angVis:1);
}
\newcommand\DrawLatitudeCircle[2][1]{
\LatitudePlane{\angEl}{#2}
\tikzset{current plane/.prefix style={scale=#1}}
\pgfmathsetmacro\sinVis{sin(#2)/cos(#2)*sin(\angEl)/cos(\angEl)}
% angle of "visibility"
\pgfmathsetmacro\angVis{asin(min(1,max(\sinVis,-1)))}
\draw[current plane] (\angVis:1) arc (\angVis:-\angVis-180:1);
\draw[current plane,dashed] (180-\angVis:1) arc (180-\angVis:\angVis:1);
}

%% document-wide tikz options and styles
\tikzset{%
>=latex,%
inner sep=0pt,%
outer sep=2pt,%
mark coordinate/.style={inner sep=0pt,outer sep=0pt,minimum size=3pt,fill=black,circle}%
}

\begin{document}

\begin{tikzpicture}

%% some definitions
\def\angEl{25} % elevation angle
\pgfmathsetmacro\H{\R*cos(\angEl)} % distance to north pole

%% draw background sphere
\fill[ball color=white] (0,0) circle (\R); % 3D lighting effect
\draw (0,0) circle (\R);

%% characteristic points
\coordinate[mark coordinate] (N) at (0,\H);
\coordinate[mark coordinate] (S) at (0,-\H);

%% meridians and latitude circles
\foreach \t in {-80,-60,...,80} { \DrawLatitudeCircle[\R]{\t} }
\foreach \t in {-5,-35,...,-175} { \DrawLongitudeCircle[\R]{\t} }
\foreach \t in {-5,-35,...,-175} { \DrawLongitudeCircle[\R]{\t} }

%% draw lines and put labels
\node[above=8pt] at (N) {$\mathbf{N}$};
\node[below=8pt] at (S) {$\mathbf{S}$};

\end{tikzpicture}

\end{document}


I just can't figure out how to align the sides of the cone to a certain latitude circle.

• Please add a minimal working example (MWE) that illustrates your problem. – percusse Sep 21 '12 at 7:48
• To the OP: Perhaps, a task for SVG ? (You might want to consider looking at Inkscape anyway. – kan Sep 21 '12 at 7:51
• This appears more like "draw it for me" rather than a genuine question. You should at least show how you attempted to solve the problem, since you state that "you're struggling with TikZ". – egreg Sep 21 '12 at 8:48
• To expand a little on the comments, this site works best as a helping hand at the precise point where you get stuck with something when a small nudge in the correct direction shows you how to proceed. So things that look like "Please do this complicated thing for me" tend not to get answers because they require a great deal of effort. To make the most of this site, you need to identify one thing that will help you where if someone knows the answer it will take them very little time to show you. So if you show what you have so far, you'll stand a greater chance of getting help. – Loop Space Sep 21 '12 at 9:13

Visibility with curved bodys is a bitch with Tikz, but you can approximate them: the first very good, the second slightly less:

## Document structure

\documentclass[tikz,border=5mm]{standalone}

\begin{document}
\pgfmathsetmacro{\R}{5}
\pgfmathsetmacro{\doubleR}{2*\R}

\newcommand{\xangle}{-30}
\newcommand{\yangle}{210}
\newcommand{\zangle}{90}

\newcommand{\xlength}{1}
\newcommand{\ylength}{1}
\newcommand{\zlength}{1}

\pgfmathsetmacro{\xx}{\xlength*cos(\xangle)}
\pgfmathsetmacro{\xy}{\xlength*sin(\xangle)}
\pgfmathsetmacro{\yx}{\ylength*cos(\yangle)}
\pgfmathsetmacro{\yy}{\ylength*sin(\yangle)}
\pgfmathsetmacro{\zx}{\zlength*cos(\zangle)}
\pgfmathsetmacro{\zy}{\zlength*sin(\zangle)}


...

\end{document}


## First picture

\begin{tikzpicture}
[   x={(\xx cm,\xy cm)},
y={(\yx cm,\yy cm)},
z={(\zx cm,\zy cm)},
scale=0.5,
]

\pgfmathsetmacro{\cylb}{-3}
\pgfmathsetmacro{\cylt}{6}

\pgfmathsetmacro{\rt}{(10-\cylt)/sqrt(3)}
\pgfmathsetmacro{\rb}{(10-\cylb)/sqrt(3)}
\fill[red,opacity=0.4] ({cos(159)*\rb},{sin(159)*\rb},{\cylb}) arc (159:291:\rb) -- ({cos(291)*\rt},{sin(291)*\rt},{\cylt}) arc (291:159:\rt) -- cycle;

\foreach \h in {10,20,...,180}
{   \foreach \a in {0,10,...,170}
{   \pgfmathsetmacro{\rt}{\R*sin(\h)}
\pgfmathsetmacro{\rb}{\R*sin(\h-10)}
\fill[green!50,draw=black] ({\rb*cos(\a)},{\rb*sin(\a)},{\R*cos(\h-190)}) arc (\a:\a+10:\rb) -- ({\rt*cos(\a+10)},{\rt*sin(\a+10)},{\R*cos(\h-180)}) arc (\a+10:\a:\rt) -- cycle;
\fill[green!50,draw=black] ({\rb*cos(-\a)},{\rb*sin(-\a)},{\R*cos(\h-190)}) arc (-\a:-\a-10:\rb) -- ({\rt*cos(-\a-10)},{\rt*sin(-\a-10)},{\R*cos(\h-180)}) arc (-\a-10:-\a:\rt) -- cycle;
}
}

\fill[red,opacity=0.4] ({cos(159)*\rb},{sin(159)*\rb},{\cylb}) arc (159:-69:\rb) -- ({cos(-69)*\rt},{sin(-69)*\rt},{\cylt}) arc (-69:159:\rt) -- cycle;

\end{tikzpicture}


## Second picture

\begin{tikzpicture}
[   x={(\xx cm,\xy cm)},
y={(\yx cm,\yy cm)},
z={(\zx cm,\zy cm)},
scale=0.5,
]

\pgfmathsetmacro{\cylbb}{-4}
\pgfmathsetmacro{\cyltb}{0.36}
\pgfmathsetmacro{\cylbt}{4.14}
\pgfmathsetmacro{\cyltt}{6}

\pgfmathsetmacro{\rt}{(9-\cyltb)/sqrt(3)}
\pgfmathsetmacro{\rb}{(9-\cylbb)/sqrt(3)}
\fill[red,opacity=0.4] ({cos(159)*\rb},{sin(159)*\rb},{\cylbb}) arc (159:291:\rb) -- ({cos(291)*\rt},{sin(291)*\rt},{\cyltb}) arc (291:159:\rt) -- cycle;

\pgfmathsetmacro{\rt}{(9-\cyltt)/sqrt(3)}
\pgfmathsetmacro{\rb}{(9-\cylbt)/sqrt(3)}
\fill[red,opacity=0.4] ({cos(159)*\rb},{sin(159)*\rb},{\cylbt}) arc (159:291:\rb) -- ({cos(291)*\rt},{sin(291)*\rt},{\cyltt}) arc (291:159:\rt) -- cycle;

\foreach \h in {10,20,...,180}
{   \foreach \a in {0,10,...,170}
{   \pgfmathsetmacro{\rt}{\R*sin(\h)}
\pgfmathsetmacro{\rb}{\R*sin(\h-10)}
\fill[green!50,draw=black] ({\rb*cos(\a)},{\rb*sin(\a)},{\R*cos(\h-190)}) arc (\a:\a+10:\rb) -- ({\rt*cos(\a+10)},{\rt*sin(\a+10)},{\R*cos(\h-180)}) arc (\a+10:\a:\rt) -- cycle;
\fill[green!50,draw=black] ({\rb*cos(-\a)},{\rb*sin(-\a)},{\R*cos(\h-190)}) arc (-\a:-\a-10:\rb) -- ({\rt*cos(-\a-10)},{\rt*sin(-\a-10)},{\R*cos(\h-180)}) arc (-\a-10:-\a:\rt) -- cycle;
}
}

\pgfmathsetmacro{\rt}{(9-\cyltb)/sqrt(3)}
\pgfmathsetmacro{\rb}{(9-\cylbb)/sqrt(3)}
\fill[red,opacity=0.4] ({cos(159)*\rb},{sin(159)*\rb},{\cylbb}) arc (159:-69:\rb) -- ({cos(-69)*\rt},{sin(-69)*\rt},{\cyltb}) arc (-69:159:\rt) -- cycle;

\pgfmathsetmacro{\rt}{(9-\cyltt)/sqrt(3)}
\pgfmathsetmacro{\rb}{(9-\cylbt)/sqrt(3)}
\fill[red,opacity=0.4] ({cos(159)*\rb},{sin(159)*\rb},{\cylbt}) arc (159:-69:\rb) -- ({cos(-69)*\rt},{sin(-69)*\rt},{\cyltt}) arc (-69:159:\rt) -- cycle;

\end{tikzpicture}


## Limitations

• The commands before the picture seem to imply that you can choose axes freely. No. It works for this configuration.
• In the second picture, a bit of "front cone" overlaps the sphere at the sides.
• the latitude lines are circles, the longitude lines are not.
• Wow, first +1 Nice result! and now +1 Very nice result! ;-) (with smiley!) from Paul. I'm on fire tonight 8-D! – Tom Bombadil Sep 21 '12 at 21:19
• I'm impressed, thank you. And the best part is: I actually understand what's going on :-) – Fladi Sep 25 '12 at 5:41

run with xelatex

\documentclass{article}
\usepackage[dvipsnames]{pstricks}
\usepackage{pst-solides3d}
\begin{document}

\begin{pspicture}[solidmemory](-4,-5)(-6,8)
\psset{unit=0.25cm,viewpoint=20 0 10 rtp2xyz,lightsrc=viewpoint,Decran=50}
\psSolid[object=tronccone,
fillcolor=red!60, r0=5, r1=2, h=6,
hollow, ngrid=36 36, name=sph2, action=none](0,0,0)
\psSolid[object=sphere, r=3, ngrid=36 36,
fillcolor=blue, name=sph1, action=none](0,0,2.9)
\psSolid[object=fusion, base=sph1 sph2, opacity=0.6, action=draw**]
\end{pspicture}

\begin{pspicture}[solidmemory](-4,-5)(-6,8)
\psset{unit=0.25cm,viewpoint=20 0 50 rtp2xyz,lightsrc=viewpoint,Decran=50}
\psSolid[object=tronccone, fillcolor=red!60, r0=5, r1=2, h=6,
incolor=green!40, hollow, ngrid=36 36, name=sph2, action=none](0,0,0)
\psSolid[object=sphere, r=3, ngrid=36 36, fillcolor=blue!40, name=sph1,
action=none](0,0,2.9)
\psSolid[object=fusion, base=sph1 sph2](0,0,0)%
\end{pspicture}

\end{document}


Any combination of cone and sphere is possible:

• Very good but the dense black grid makes them look a bit dark. – kiss my armpit Sep 22 '12 at 6:16
• Wow, I never tried pstricks, but that actually convinced me to give it a try. I admire how easy it is to draw solid 3D objects compared to TikZ. – Fladi Sep 25 '12 at 5:47