# Drawing an arc to this image

I used the result in this post to achieve a rotation of a cone about an 3D axis. I am unsure on how to implement the following to this image:

I would like the imaginary lines that run along the 'volume of the cone' to be dashed to promote a better sense of the 3D nature of the image. I also need to draw an arc between the central lines of both cones to label the rotation angle $\vartheta$. Also is there any advice to make it look more '3D-like'?

MWE

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usepackage{filecontents}
\usetikzlibrary{arrows,shapes,backgrounds,fit,decorations.pathreplacing,chains,snakes,positioning,angles,quotes}

\newcommand{\savedx}{0}
\newcommand{\savedy}{0}
\newcommand{\savedz}{0}

\tikzset{
pics/tester/.style n args={3}{
code = {%

\def\x{1}
\def\y{3.4}
\def\R{\x+0.009}
\def\yc{\y+0.08}
\def\e{0.6}

(-\x,\y) -- (-\x,\yc) arc (180:360:{\R} and \e) -- (\x,\y) -- (0,0) -- cycle;
\draw[fill=#2,#3]
(0,\yc) circle ({\R} and \e);
\draw[#3]
(-\x,\y) -- (0,0) -- (\x,\y);
\draw[#3]
(0,\yc) circle ({\R} and \e);

\draw[line width=1pt] (0,0,0) -- (0,4,0);

}}}

\newcommand{\rotateRPY}[4][0/0/0]% point to be saved to \savedxyz, roll, pitch, yaw
{   \pgfmathsetmacro{\rollangle}{#2}
\pgfmathsetmacro{\pitchangle}{#3}
\pgfmathsetmacro{\yawangle}{#4}

% to what vector is the x unit vector transformed, and which 2D vector is this?
\pgfmathsetmacro{\newxx}{cos(\yawangle)*cos(\pitchangle)}% a
\pgfmathsetmacro{\newxy}{sin(\yawangle)*cos(\pitchangle)}% d
\pgfmathsetmacro{\newxz}{-sin(\pitchangle)}% g
\path (\newxx,\newxy,\newxz);
\pgfgetlastxy{\nxx}{\nxy};

% to what vector is the y unit vector transformed, and which 2D vector is this?
\pgfmathsetmacro{\newyx}{cos(\yawangle)*sin(\pitchangle)*sin(\rollangle)-sin(\yawangle)*cos(\rollangle)}% b
\pgfmathsetmacro{\newyy}{sin(\yawangle)*sin(\pitchangle)*sin(\rollangle)+ cos(\yawangle)*cos(\rollangle)}% e
\pgfmathsetmacro{\newyz}{cos(\pitchangle)*sin(\rollangle)}% h
\path (\newyx,\newyy,\newyz);
\pgfgetlastxy{\nyx}{\nyy};

% to what vector is the z unit vector transformed, and which 2D vector is this?
\pgfmathsetmacro{\newzx}{cos(\yawangle)*sin(\pitchangle)*cos(\rollangle)+ sin(\yawangle)*sin(\rollangle)}
\pgfmathsetmacro{\newzy}{sin(\yawangle)*sin(\pitchangle)*cos(\rollangle)-cos(\yawangle)*sin(\rollangle)}
\pgfmathsetmacro{\newzz}{cos(\pitchangle)*cos(\rollangle)}
\path (\newzx,\newzy,\newzz);
\pgfgetlastxy{\nzx}{\nzy};

% transform the point given by #1
\foreach \x/\y/\z in {#1}
{   \pgfmathsetmacro{\transformedx}{\x*\newxx+\y*\newyx+\z*\newzx}
\pgfmathsetmacro{\transformedy}{\x*\newxy+\y*\newyy+\z*\newzy}
\pgfmathsetmacro{\transformedz}{\x*\newxz+\y*\newyz+\z*\newzz}
\xdef\savedx{\transformedx}
\xdef\savedy{\transformedy}
\xdef\savedz{\transformedz}
}
}

\tikzset{RPY/.style={x={(\nxx,\nxy)},y={(\nyx,\nyy)},z={(\nzx,\nzy)}}}

\begin{document}

\begin{tikzpicture}
\pic {tester={0.08}{black!6!white}{densely dashed}};
\rotateRPY{0}{0}{91}
\begin{scope}[RPY]
\pic {tester={0.2}{blue!14!white}{}};
\end{scope}
\end{tikzpicture}

\end{document}


I would like then like to overlay both of the cones with a similar one that is squashed in one direction, but stretched by an equivalent factor in the other direction. The above MWE has a few flaws in achieving this which shows for one of the cones:

Namely, bases of the cones are not in the same plane. The red cone is stretched in one direction, but is not squeezed in the other direction.

I would like to argue that such things are drawn much more conveniently with the tikz-3dplot package and the 3d library.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\makeatletter
% small fix for canvas is xy plane at z % https://tex.stackexchange.com/a/48776/121799
\tikzoption{canvas is xy plane at z}[]{%
\def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
\def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
\def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
\tikz@canvas@is@plane}
\makeatother

\begin{document}

\tdplotsetmaincoords{110}{-165} % - because of difference between active and passive transformations...
\begin{tikzpicture}
%\draw (-5,-2.5) rectangle (1.5,5);
\begin{scope}[tdplot_main_coords,thick]
% just in case you want to get an intuition for the coordinates/projections
%  \draw[-latex] (0,0,0) -- (1,0,0) coordinate (X) node[below]{$x$};
%  \draw[-latex] (0,0,0) -- (0,1,0) coordinate (Y) node[right]{$y$};
%  \draw[-latex] (0,0,0) -- (0,0,1) coordinate (Z) node[left]{$z$};
% origin
\coordinate (O) at (0,0,0);
% top
\begin{scope}[canvas is xy plane at z=4,dashed]
\draw[thick,solid] (O) -- (0,0);
arc(\tdplotmainphi:\tdplotmainphi+180:1) -- (O) -- cycle;
\draw[fill opacity=0.3,fill=gray!80] circle (1);
\end{scope}
% left
\begin{scope}[canvas is yz plane at x=4]
\draw[thick] (O) -- (0,0);
\pgfmathsetmacro{\MyThetaMax}{atan(tan(\tdplotmaintheta)*sin(90+\tdplotmainphi))}
(\MyThetaMax:1)
arc(\MyThetaMax:\MyThetaMax+180:1) -- (O) -- cycle;
\draw[fill opacity=0.3,fill=gray] circle (1);
\end{scope}
% arc
\begin{scope}[canvas is xz plane at y=0,xscale=-1]
\draw[-latex] (0,1) arc(90:180:1) node[midway,above left]{$\vartheta$};
\end{scope}
\end{scope}
\end{tikzpicture}
\end{document}


The advantage is that you can change the view angles at will.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\makeatletter
% small fix for canvas is xy plane at z % https://tex.stackexchange.com/a/48776/121799
\tikzoption{canvas is xy plane at z}[]{%
\def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
\def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
\def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
\tikz@canvas@is@plane}
\makeatother

\begin{document}
\foreach \X in {5,15,...,355}
{\tdplotsetmaincoords{120+20*sin(\X)}{\X} % - because of difference between active and passive transformations...
\begin{tikzpicture}
\path[use as bounding box] (-5,-2.5) rectangle (5,5);
\begin{scope}[tdplot_main_coords,thick]
% just in case you want to get an intuition for the coordinates/projections
%  \draw[-latex] (0,0,0) -- (1,0,0) coordinate (X) node[below]{$x$};
%  \draw[-latex] (0,0,0) -- (0,1,0) coordinate (Y) node[right]{$y$};
%  \draw[-latex] (0,0,0) -- (0,0,1) coordinate (Z) node[left]{$z$};
% origin
\coordinate (O) at (0,0,0);
% left
\begin{scope}[canvas is yz plane at x=4]
\pgfmathtruncatemacro{\ttest}{sign(cos(\tdplotmainphi+90))}
\ifnum\ttest=1
\pgfmathsetmacro{\MyThetaMax}{atan(tan(\tdplotmaintheta)*sin(90+\tdplotmainphi))}
(\MyThetaMax:1)
arc(\MyThetaMax:\MyThetaMax+180:1) -- (O) -- cycle;
\draw[fill=gray!30] circle (1);
\draw[thick] (O) -- (0,0);
\else
\draw[fill=gray!30] circle (1);
\draw[thick] (O) -- (0,0);
\pgfmathsetmacro{\MyThetaMax}{atan(tan(\tdplotmaintheta)*sin(90+\tdplotmainphi))}
(\MyThetaMax:1)
arc(\MyThetaMax:\MyThetaMax+180:1) -- (O) -- cycle;
\fi
\end{scope}
% top
\begin{scope}[canvas is xy plane at z=4,dashed]
\draw[thick,solid] (O) -- (0,0);1
arc(\tdplotmainphi:\tdplotmainphi+180:1) -- (O) -- cycle;
\draw[fill opacity=0.3,fill=gray!80] circle (1);
\end{scope}
% arc
%   \begin{scope}[canvas is xz plane at y=0,xscale=-1]
%    \draw[-latex] (0,1) arc(90:180:1) node[midway,above left]{$\vartheta$};
%   \end{scope}
\end{scope}
\end{tikzpicture}}
\end{document}


As for the "squashed" shape: it took me some time to derive the (hopefully) correct formula for the visibility angle \MyThetaMax. Other than that it is almost trivial: draw ellipses in the respective planes and then repeat the above.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}

\makeatletter
% small fix for canvas is xy plane at z % https://tex.stackexchange.com/a/48776/121799
\tikzoption{canvas is xy plane at z}[]{%
\def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
\def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
\def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
\tikz@canvas@is@plane}
\makeatother

\begin{document}

\tdplotsetmaincoords{110}{-165} % - because of difference between active and passive transformations...
\begin{tikzpicture}
%\draw (-5,-2.5) rectangle (1.5,5);
\begin{scope}[tdplot_main_coords,thick]
% just in case you want to get an intuition for the coordinates/projections
%  \draw[-latex] (0,0,0) -- (1,0,0) coordinate (X) node[below]{$x$};
%  \draw[-latex] (0,0,0) -- (0,1,0) coordinate (Y) node[right]{$y$};
%  \draw[-latex] (0,0,0) -- (0,0,1) coordinate (Z) node[left]{$z$};
% origin
\coordinate (O) at (0,0,0);
% top
\begin{scope}[canvas is xy plane at z=4,dashed]
\draw[thick,solid] (O) -- (0,0);
arc(\tdplotmainphi:\tdplotmainphi+180:1) -- (O) -- cycle;
\draw[fill opacity=0.3,fill=gray!80] circle (1);
% squashed shape
(\tdplotmainphi:2 and 1)
arc(\tdplotmainphi:\tdplotmainphi+180:2 and 1) -- (O) -- cycle;
\draw[fill opacity=0.1,fill=gray!80] circle (2 and 1);
\end{scope}
% left
\begin{scope}[canvas is yz plane at x=4]
\draw[thick] (O) -- (0,0);
\pgfmathsetmacro{\MyThetaMax}{atan(tan(\tdplotmaintheta)*sin(90+\tdplotmainphi))}
(\MyThetaMax:1)
arc(\MyThetaMax:\MyThetaMax+180:1) -- (O) -- cycle;
\draw[fill opacity=0.3,fill=gray] circle (1);
% squash again
\pgfmathsetmacro{\MyThetaMax}{atan(tan(\tdplotmaintheta)*sin(90+\tdplotmainphi)*2)}
lower  left=red]
(\MyThetaMax:1 and 2)
arc(\MyThetaMax:\MyThetaMax+180:1 and 2) -- (O) -- cycle;
\draw[fill opacity=0.1,fill=gray] circle (1 and 2);
\end{scope}
% arc
\begin{scope}[canvas is xz plane at y=0,xscale=-1]
\draw[-latex] (0,1) arc(90:180:1) node[midway,above left]{$\vartheta$};
\end{scope}
\end{scope}
\end{tikzpicture}
\end{document}


Here's another attempt. I thought the above one would match your description.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}

\makeatletter
% small fix for canvas is xy plane at z % https://tex.stackexchange.com/a/48776/121799
\tikzoption{canvas is xy plane at z}[]{%
\def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
\def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
\def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
\tikz@canvas@is@plane}
\makeatother

\begin{document}

\tdplotsetmaincoords{110}{-165} % - because of difference between active and passive transformations...
\begin{tikzpicture}
%\draw (-5,-2.5) rectangle (1.5,5);
\begin{scope}[tdplot_main_coords,thick]
% just in case you want to get an intuition for the coordinates/projections
%  \draw[-latex] (0,0,0) -- (1,0,0) coordinate (X) node[below]{$x$};
%  \draw[-latex] (0,0,0) -- (0,1,0) coordinate (Y) node[right]{$y$};
%  \draw[-latex] (0,0,0) -- (0,0,1) coordinate (Z) node[left]{$z$};
% origin
\coordinate (O) at (0,0,0);
% top
\begin{scope}[canvas is xy plane at z=4,dashed]
\draw[thick,solid] (O) -- (0,0);
% squashed shape
\pgfmathsetmacro{\MyPhiMax}{atan(tan(\tdplotmainphi)*sin(90+\tdplotmaintheta))}
(\MyPhiMax:2 and 0.5)
arc(\MyPhiMax:\MyPhiMax+180:2 and 0.5) -- (O) -- cycle;
\draw[fill opacity=0.1,fill=gray!80] circle (2 and 0.5);
% unsquashed
arc(\tdplotmainphi:\tdplotmainphi+180:1) -- (O) -- cycle;
\draw[fill opacity=0.3,fill=gray!80] circle (1);
\end{scope}
% left
\begin{scope}[canvas is yz plane at x=4]
\draw[thick] (O) -- (0,0);
% squash again
\pgfmathsetmacro{\MyThetaMax}{atan(tan(\tdplotmaintheta)*sin(90+\tdplotmainphi)*4)}
lower  left=red]
(\MyThetaMax:0.5 and 2)
arc(\MyThetaMax:\MyThetaMax+180:0.5 and 2) -- (O) -- cycle;
\draw[fill opacity=0.1,fill=gray] circle (0.5 and 2);
% unsquashed
\pgfmathsetmacro{\MyThetaMax}{atan(tan(\tdplotmaintheta)*sin(90+\tdplotmainphi))}
(\MyThetaMax:1)
arc(\MyThetaMax:\MyThetaMax+180:1) -- (O) -- cycle;
\draw[fill opacity=0.3,fill=gray] circle (1);
\end{scope}
% arc
\begin{scope}[canvas is xz plane at y=0,xscale=-1]
\draw[-latex] (0,1) arc(90:180:1) node[midway,above left]{$\vartheta$};
\end{scope}
\end{scope}
\end{tikzpicture}
\end{document}


• We keep crossing paths ;) Great answer. How could I change the lines running along the volume of the cone to be dashed?
– Sid
Aug 28, 2018 at 22:00
• Also the animation example has the function sign that isn't recognised?
– Sid
Aug 28, 2018 at 22:02
• @Sid In the "top" scope I just added dashed to the scope options. Does adding dashed to the left scope give you want you want? (Probably I just do not understand.) And what do you mean by sign is not recognized? On my TeXLive installation the code gives me a multipage pdf without any problems which I convert using convert to the animated gif.
– user121799
Aug 28, 2018 at 22:05
• I got the 'unknown function sign' on the console. On a related question, I wanted to overlay another cone over both the dashed and non-dashed cones, but which is stretched along one of the axes and red in colour. This was why I originally had the \tikzset approach. How could I do this?
– Sid
Aug 28, 2018 at 22:13
• For the record: Jake's patch is now incorporated in v3.1 of TikZ. Jan 15, 2019 at 19:19