# Arrows with spherical (conical) tips

To pag. 81 of the asymptote tutorial there are spherical arrows tips:

I like the tips of the first image and of the 2nd image arrow=Arrow3() that it can be used also in 2D. Do this tips exists only in asymptote or also in TikZ, pstricks, or into a specific symbols or packages?

• Please have a look at this most beautiful answer: tex.stackexchange.com/a/267497. That is, you have mistagged your question. Instead of symbols it has to be symbol 1. ;-)
– user194703
Commented Apr 12, 2020 at 19:40
• @Schrödinger'scat Yes...and happy eastern..an peraphs my is a duplicate :-)...but does is exists a symbol? Commented Apr 12, 2020 at 19:43
• Yes, one symbol: Symbol 1. ;-) You can always make a symbol from a tikzpicture. I guess if you rewrite your question in this way, it is not a duplicate. Also call the arrows spherical with ph.
– user194703
Commented Apr 12, 2020 at 19:44
• @Schrödinger'scat Please, edit my question. I'm scarce in english :-( of course. Commented Apr 12, 2020 at 19:45
• Well, for arbitrary view angles you could use Symbol 1's answer, at least as a starting point. If you only want the arrows as symbols, i.e. for some fixed view, a much shorter code will do.
– user194703
Commented Apr 12, 2020 at 20:02

This is just for fun. Some considerations concerning the projection of a 3d cone on the screen. The main purpose is to explain why I think that the extremal rays from the tip are in general on tangents to the ellipse that emerges from projecting the base circle on the screen. The projection of the cone is a triangle. One can compute the intersection of the cone with the base analytically to obtain

\documentclass[tikz,border=3mm]{standalone}
\tikzset{pics/3d cone/.style={code={
\tikzset{3d cone/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/3d cone/##1}}%
% \itest determines whether the projection of the tip of the cone is inside
% the projection of the base circle, in which case \itest=1
\pgfmathtruncatemacro{\itest}{-1*sign(\pv{h}*abs(cos(\pv{theta}))-\pv{r}*abs(sin(\pv{theta})))}
% \ttest checks whether we look at the cone from the bottom or top,
% in the latter case \ttest=1
\pgfmathtruncatemacro{\ttest}{sign(sin(\pv{theta}))}%
% alpha crit
\pgfmathsetmacro{\alphacrit}{90-atan2((2*\pv{h}*\pv{r}*sin(\pv{theta})*cos(\pv{theta}))/(pow(\pv{h}*cos(\pv{theta}),2) + pow(\pv{r}*sin(\pv{theta}),2)),
(pow(\pv{h}*cos(\pv{theta}),2) - pow(\pv{r}*sin(\pv{theta}),2))/(pow(\pv{h}*cos(\pv{theta}),2)  +
pow(\pv{r}*sin(\pv{theta}),2))}%
\begin{scope}[rotate=\pv{phi}]
\ifnum\itest=1
\ifnum\ttest=1
\path[3d cone/base] (0,0)
\path[3d cone/mantle]
\else
\path[3d cone/mantle]
\path[3d cone/base] (0,0)
\fi
\else
\ifnum\ttest=1
\path[3d cone/base] (0,0)
\path[3d cone/mantle]
plot[variable=\t,domain=\alphacrit:360-\alphacrit,smooth,samples=51]
({\pv{r}*sin(\pv{theta})*cos(\t)},{\pv{r}*sin(\t)})
-- ({\pv{h}*cos(\pv{theta})},0) -- cycle;
\else
\path[3d cone/mantle]
plot[variable=\t,domain=\alphacrit:360-\alphacrit,smooth,samples=51]
({\pv{r}*sin(\pv{theta})*cos(\t)},{\pv{r}*sin(\t)})
-- ({\pv{h}*cos(\pv{theta})},0) -- cycle;
\path[3d cone/base] (0,0)
\fi
\fi
\end{scope}
}},3d cone/.cd,h/.initial=1,r/.initial=1,theta/.initial=0,phi/.initial=90,
base/.style={fill=gray},
lower left=gray, upper left=gray!60!black, upper right=gray, lower
postaction={left color=gray,right color=gray,middle color=gray!20,
mantle contour/.style={draw=gray,very thin},
from top/.style={inner color=gray!20,outer color=gray,opacity=0.7}}
\begin{document}
\foreach \Angle in {5,15,...,355}
{\begin{tikzpicture}
\path[use as bounding box] (-4,-4) rectangle (4,4);
\path (0,0) pic{3d cone={theta=\Angle,phi={90+30*sin(\Angle)},h=3,r=2}};
\end{tikzpicture}}
\end{document}


This can be used to construct an arrow. The shading is stolen from here.

\documentclass[tikz,border=3mm]{standalone}
\tikzset{pics/3d arrow/.style={code={
\tikzset{3d arrow/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/3d arrow/##1}}%
% \itest determines whether the projection of the tip of the cone is inside
% the projection of the base circle, in which case \itest=1
\pgfmathtruncatemacro{\itest}{-1*sign(\pv{h}*abs(cos(\pv{theta}))-\pv{R}*abs(sin(\pv{theta})))}
% \ttest checks whether we look at the cone from the bottom or top,
% in the latter case \ttest=1
\pgfmathtruncatemacro{\ttest}{sign(sin(\pv{theta}))}%
% alpha crit
\pgfmathsetmacro{\alphacrit}{90-atan2((2*\pv{h}*\pv{R}*sin(\pv{theta})*cos(\pv{theta}))/(pow(\pv{h}*cos(\pv{theta}),2) + pow(\pv{R}*sin(\pv{theta}),2)),
(pow(\pv{h}*cos(\pv{theta}),2) - pow(\pv{R}*sin(\pv{theta}),2))/(pow(\pv{h}*cos(\pv{theta}),2)  +
pow(\pv{R}*sin(\pv{theta}),2))}%
%\pgfmathsetmacro{\alphacrit}{min(\alphacrit,180-\alphacrit)}
% \path (-4,4) node[below right]
% {$t=\ttest,i=\itest,\alpha_\mathrm{crit}=\alphacrit,\theta=\pv{theta},\phi=\pv{phi}$};
\begin{scope}[rotate=\pv{phi}]
\path  ({\pv{h}*cos(\pv{theta})},0) coordinate (tip);
\ifnum\itest=1
\ifnum\ttest=1
\tikzset{3d arrow/shaft}
\path[3d arrow/base] (0,0)
\path[3d arrow/mantle]
\tikzset{3d arrow/mantle extra}
\else
\path[3d arrow/mantle]
\tikzset{3d arrow/mantle extra}
\path[3d arrow/base] (0,0)
\tikzset{3d arrow/shaft}
\fi
\else
\ifnum\ttest=1
\tikzset{3d arrow/shaft}
\path[3d arrow/base] (0,0)
\pgfmathsetmacro{\alphamax}{(\alphacrit<90 ? 360-\alphacrit :-\alphacrit)}
\path[3d arrow/mantle]
plot[variable=\t,domain=\alphacrit:\alphamax,smooth,samples=51]
({\pv{R}*sin(\pv{theta})*cos(\t)},{\pv{R}*sin(\t)})
-- ({\pv{h}*cos(\pv{theta})},0) -- cycle;
\tikzset{3d arrow/mantle extra}
\else
\path[3d arrow/mantle]
plot[variable=\t,domain=\alphacrit:360-\alphacrit,smooth,samples=51]
({\pv{R}*sin(\pv{theta})*cos(\t)},{\pv{R}*sin(\t)})
-- ({\pv{h}*cos(\pv{theta})},0) -- cycle;
\tikzset{3d arrow/mantle extra}
\path[3d arrow/base] (0,0)
\tikzset{3d arrow/shaft}
\fi
\fi
\end{scope}
}},3d arrow/.cd,h/.initial=1,% height of cone
L/.initial=2,% length of shaft
theta/.initial=0,phi/.initial=90,
base/.style={fill=gray!70},
mantle/.style={fill=gray!20},
mantle contour/.style={draw=gray,very thin},
from top/.style={inner color=gray!20,outer color=gray,opacity=0.7},
mantle extra/.code={
\ifnum\itest=1
\foreach \XX in {-45,45,135,225}
{\foreach \YY [evaluate = {\ZZ=30;}] in {0,2,...,30}
{\fill [black, fill opacity = 1/50]
(tip) --
plot[variable=\t,domain=-\ZZ:\ZZ]
({\pv{R}*sin(\pv{theta})*cos(\XX-\YY+\t)},{\pv{R}*sin(\XX-\YY+\t)})
-- cycle;}}
\else
\pgfmathsetmacro{\pft}{(cos(\pv{theta})>0 ? 0 :180)}
\foreach \XX in {135,225}
{\foreach \YY [evaluate = {\ZZ=30;}] in {0,2,...,30}
{\fill [black, fill opacity = 1/50]
(tip) --
plot[variable=\t,domain=-\ZZ:\ZZ]
({\pv{R}*sin(\pv{theta})*cos(\pft+\XX-\YY+\t)},{\pv{R}*sin(\pft+\XX-\YY+\t)})
-- cycle;}}
\fi
},
shaft/.code={
\pgfmathsetmacro{\betamax}{(cos(\pv{theta})>0 ? 270 :-90)}
\path[top color=gray!80,bottom color=black,middle color=gray!10,
shading angle=\pv{phi}] (0,\pv{r}) arc[start angle=90,end angle=\betamax,
({-\pv{L}*cos(\pv{theta})},-\pv{r})
arc[start angle=\betamax,end angle=90,
\ifnum\ttest=-1
\fi
}}
\begin{document}
\foreach \Angle in {5,15,...,355}
{\begin{tikzpicture}
\path[use as bounding box] (-4,-4) rectangle (4,4);
\path (0,0) pic{3d arrow={theta=\Angle,phi={90+30*sin(\Angle)},h=3,R=2}};
\end{tikzpicture}}
\end{document}


This can be used in the usual way to create a symbol.

\documentclass{article}
\usepackage{tikz}
\usepackage{scalerel}
\tikzset{pics/3d arrow/.style={code={
\tikzset{3d arrow/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/3d arrow/##1}}%
% \itest determines whether the projection of the tip of the cone is inside
% the projection of the base circle, in which case \itest=1
\pgfmathtruncatemacro{\itest}{-1*sign(\pv{h}*abs(cos(\pv{theta}))-\pv{R}*abs(sin(\pv{theta})))}
% \ttest checks whether we look at the cone from the bottom or top,
% in the latter case \ttest=1
\pgfmathtruncatemacro{\ttest}{sign(sin(\pv{theta}))}%
% alpha crit
\pgfmathsetmacro{\alphacrit}{90-atan2((2*\pv{h}*\pv{R}*sin(\pv{theta})*cos(\pv{theta}))/(pow(\pv{h}*cos(\pv{theta}),2) + pow(\pv{R}*sin(\pv{theta}),2)),
(pow(\pv{h}*cos(\pv{theta}),2) - pow(\pv{R}*sin(\pv{theta}),2))/(pow(\pv{h}*cos(\pv{theta}),2)  +
pow(\pv{R}*sin(\pv{theta}),2))}%
%\pgfmathsetmacro{\alphacrit}{min(\alphacrit,180-\alphacrit)}
% \path (-4,4) node[below right]
% {$t=\ttest,i=\itest,\alpha_\mathrm{crit}=\alphacrit,\theta=\pv{theta},\phi=\pv{phi}$};
\begin{scope}[rotate=\pv{phi}]
\path  ({\pv{h}*cos(\pv{theta})},0) coordinate (tip);
\ifnum\itest=1
\ifnum\ttest=1
\tikzset{3d arrow/shaft}
\path[3d arrow/base] (0,0)
\path[3d arrow/mantle]
\tikzset{3d arrow/mantle extra}
\else
\path[3d arrow/mantle]
\tikzset{3d arrow/mantle extra}
\path[3d arrow/base] (0,0)
\tikzset{3d arrow/shaft}
\fi
\else
\ifnum\ttest=1
\tikzset{3d arrow/shaft}
\path[3d arrow/base] (0,0)
\pgfmathsetmacro{\alphamax}{(\alphacrit<90 ? 360-\alphacrit :-\alphacrit)}
\path[3d arrow/mantle]
plot[variable=\t,domain=\alphacrit:\alphamax,smooth,samples=51]
({\pv{R}*sin(\pv{theta})*cos(\t)},{\pv{R}*sin(\t)})
-- ({\pv{h}*cos(\pv{theta})},0) -- cycle;
\tikzset{3d arrow/mantle extra}
\else
\path[3d arrow/mantle]
plot[variable=\t,domain=\alphacrit:360-\alphacrit,smooth,samples=51]
({\pv{R}*sin(\pv{theta})*cos(\t)},{\pv{R}*sin(\t)})
-- ({\pv{h}*cos(\pv{theta})},0) -- cycle;
\tikzset{3d arrow/mantle extra}
\path[3d arrow/base] (0,0)
\tikzset{3d arrow/shaft}
\fi
\fi
\end{scope}
}},3d arrow/.cd,h/.initial=1,% height of cone
L/.initial=2,% length of shaft
theta/.initial=0,phi/.initial=90,
base/.style={fill=gray!70},
mantle/.style={fill=gray!20},
mantle contour/.style={draw=gray,very thin},
from top/.style={inner color=gray!20,outer color=gray,opacity=0.7},
mantle extra/.code={
\ifnum\itest=1
\foreach \XX in {-45,45,135,225}
{\foreach \YY [evaluate = {\ZZ=30;}] in {0,2,...,30}
{\fill [black, fill opacity = 1/50]
(tip) --
plot[variable=\t,domain=-\ZZ:\ZZ]
({\pv{R}*sin(\pv{theta})*cos(\XX-\YY+\t)},{\pv{R}*sin(\XX-\YY+\t)})
-- cycle;}}
\else
\pgfmathsetmacro{\pft}{(cos(\pv{theta})>0 ? 0 :180)}
\foreach \XX in {135,225}
{\foreach \YY [evaluate = {\ZZ=30;}] in {0,2,...,30}
{\fill [black, fill opacity = 1/50]
(tip) --
plot[variable=\t,domain=-\ZZ:\ZZ]
({\pv{R}*sin(\pv{theta})*cos(\pft+\XX-\YY+\t)},{\pv{R}*sin(\pft+\XX-\YY+\t)})
-- cycle;}}
\fi
},
shaft/.code={
\pgfmathsetmacro{\betamax}{(cos(\pv{theta})>0 ? 270 :-90)}
\path[top color=gray!80,bottom color=black,middle color=gray!10,
shading angle=\pv{phi}] (0,\pv{r}) arc[start angle=90,end angle=\betamax,
({-\pv{L}*cos(\pv{theta})},-\pv{r})
arc[start angle=\betamax,end angle=90,
\ifnum\ttest=-1
\fi
}}
\newsavebox\SBTikzTDrightarrow
\newsavebox\SBTikzTDleftarrow
\sbox\SBTikzTDrightarrow{\begin{tikzpicture}
\pic{3d arrow={theta=-20,phi=0,h=3,R=2,L=8}};
\end{tikzpicture}}
\sbox\SBTikzTDleftarrow{\begin{tikzpicture}
\pic{3d arrow={theta=20,phi=180,h=3,R=2,L=8}};
\end{tikzpicture}}
\newcommand{\TDrightarrow}{\mathrel{\scalerel*{\usebox\SBTikzTDrightarrow}{\rightarrow}}}
\newcommand{\TDleftarrow}{\mathrel{\scalerel*{\usebox\SBTikzTDleftarrow}{\leftarrow}}}
\begin{document}
$a\TDrightarrow b\TDleftarrow c$

$a\rightarrow b\leftarrow c$
\end{document}


• Impressive. :-) I don't understand anything about Asymptote :-) But does a conical 3D vector symbol above a letter exist or should it be created? I would also like to understand how a 3D symbol can be generated. Thank you very much for your answer. Commented Apr 13, 2020 at 10:56
• @Sebastiano I meanwhile think one can simplify this quite a bit. Basically one needs to draw a rectangle. BTW, you may not prematurely accept this answer, maybe someone else shows up and answers the question, i.e. provides you with a beautiful arrow.
– user194703
Commented Apr 13, 2020 at 12:59