5

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

enter image description here enter image description here

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?

Sebastiano
  • 54,118
  • 1
    Please have a look at this most beautiful answer: https://tex.stackexchange.com/a/267497. That is, you have mistagged your question. Instead of symbols it has to be symbol 1. ;-) –  Apr 12 '20 at 19:40
  • @Schrödinger'scat Yes...and happy eastern..an peraphs my is a duplicate :-)...but does is exists a symbol? – Sebastiano Apr 12 '20 at 19:43
  • 2
    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. –  Apr 12 '20 at 19:44
  • @Schrödinger'scat Please, edit my question. I'm scarce in english :-( of course. – Sebastiano Apr 12 '20 at 19:45
  • @Schrödinger'scat I have written "sferical" in italian language :-))) – Sebastiano Apr 12 '20 at 19:48
  • 2
    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. –  Apr 12 '20 at 20:02
  • I prefer the symbol of the arrow. Thank you very much. – Sebastiano Apr 12 '20 at 20:06
  • @Schrödinger'scat I have not understood all your comment :-)))...I would to try it over a symbol or on axes in 2D. You are (and others users) free with your inspiration of beautiful arts. – Sebastiano Apr 12 '20 at 21:36

1 Answers1

3

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}
\usetikzlibrary{shadings}
\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) 
        circle[x radius={\pv{r}*sin(\pv{theta})},y radius=\pv{r}];
      \path[3d cone/mantle] 
      circle[x radius={\pv{r}*sin(\pv{theta})},y radius=\pv{r}];
     \else
      \path[3d cone/mantle] 
      circle[x radius={\pv{r}*sin(\pv{theta})},y radius=\pv{r}];
      \path[3d cone/base] (0,0) 
        circle[x radius={\pv{r}*sin(\pv{theta})},y radius=\pv{r}];
     \fi    
    \else
     \ifnum\ttest=1
      \path[3d cone/base] (0,0) 
        circle[x radius={\pv{r}*sin(\pv{theta})},y radius=\pv{r}];
      \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) 
        circle[x radius={\pv{r}*sin(\pv{theta})},y radius=\pv{r}];
     \fi
    \fi 
    \end{scope}
    }},3d cone/.cd,h/.initial=1,r/.initial=1,theta/.initial=0,phi/.initial=90,
    base/.style={fill=gray},
    mantle/.style={shading=bilinear interpolation,
   lower left=gray, upper left=gray!60!black, upper right=gray, lower
   right=white,shading angle=\pv{phi}-135,opacity=0.7,
   postaction={left color=gray,right color=gray,middle color=gray!20,
   shading angle=\pv{phi},opacity=0.7}},
   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}

enter image description here

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

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{shadings}
\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) 
        circle[x radius={\pv{R}*sin(\pv{theta})},y radius=\pv{R}];
      \path[3d arrow/mantle] 
      circle[x radius={\pv{R}*sin(\pv{theta})},y radius=\pv{R}];
      \tikzset{3d arrow/mantle extra}
     \else
      \path[3d arrow/mantle] 
      circle[x radius={\pv{R}*sin(\pv{theta})},y radius=\pv{R}];
      \tikzset{3d arrow/mantle extra}     
      \path[3d arrow/base] (0,0) 
        circle[x radius={\pv{R}*sin(\pv{theta})},y radius=\pv{R}];
      \tikzset{3d arrow/shaft}  
     \fi    
    \else
     \ifnum\ttest=1
      \tikzset{3d arrow/shaft} 
      \path[3d arrow/base] (0,0) 
        circle[x radius={\pv{R}*sin(\pv{theta})},y radius=\pv{R}];
      \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) 
        circle[x radius={\pv{R}*sin(\pv{theta})},y radius=\pv{R}];  
      \tikzset{3d arrow/shaft}  
     \fi
    \fi 
    \end{scope}
    }},3d arrow/.cd,h/.initial=1,% height of cone
    R/.initial=1,% radius of cone
    r/.initial=0.5,% radius of shaft
    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,
    x radius={\pv{r}*sin(\pv{theta})},y radius=\pv{r}] -- 
    ({-\pv{L}*cos(\pv{theta})},-\pv{r}) 
    arc[start angle=\betamax,end angle=90,
    x radius={\pv{r}*sin(\pv{theta})},y radius=\pv{r}] -- cycle;
   \ifnum\ttest=-1
    \fill[gray] ({-\pv{L}*cos(\pv{theta})},0) circle[x radius={\pv{r}*sin(\pv{theta})},y radius=\pv{r}];
   \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}

enter image description here

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) 
        circle[x radius={\pv{R}*sin(\pv{theta})},y radius=\pv{R}];
      \path[3d arrow/mantle] 
      circle[x radius={\pv{R}*sin(\pv{theta})},y radius=\pv{R}];
      \tikzset{3d arrow/mantle extra}
     \else
      \path[3d arrow/mantle] 
      circle[x radius={\pv{R}*sin(\pv{theta})},y radius=\pv{R}];
      \tikzset{3d arrow/mantle extra}     
      \path[3d arrow/base] (0,0) 
        circle[x radius={\pv{R}*sin(\pv{theta})},y radius=\pv{R}];
      \tikzset{3d arrow/shaft}  
     \fi    
    \else
     \ifnum\ttest=1
      \tikzset{3d arrow/shaft} 
      \path[3d arrow/base] (0,0) 
        circle[x radius={\pv{R}*sin(\pv{theta})},y radius=\pv{R}];
      \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) 
        circle[x radius={\pv{R}*sin(\pv{theta})},y radius=\pv{R}];  
      \tikzset{3d arrow/shaft}  
     \fi
    \fi 
    \end{scope}
    }},3d arrow/.cd,h/.initial=1,% height of cone
    R/.initial=1,% radius of cone
    r/.initial=0.5,% radius of shaft
    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,
    x radius={\pv{r}*sin(\pv{theta})},y radius=\pv{r}] -- 
    ({-\pv{L}*cos(\pv{theta})},-\pv{r}) 
    arc[start angle=\betamax,end angle=90,
    x radius={\pv{r}*sin(\pv{theta})},y radius=\pv{r}] -- cycle;
   \ifnum\ttest=-1
    \fill[gray] ({-\pv{L}*cos(\pv{theta})},0) circle[x radius={\pv{r}*sin(\pv{theta})},y radius=\pv{r}];
   \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}

enter image description here

  • 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. – Sebastiano Apr 13 '20 at 10:56
  • 1
    @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. –  Apr 13 '20 at 12:59
  • Ok, then I remove the check green mark. – Sebastiano Apr 13 '20 at 15:41
  • 2
    @Sebastiano I added an arrow head, finally. –  Apr 15 '20 at 06:12
  • I thank you infinitely: but if I wanted to put your ahahah "missile" as a symbol on a character what should I do? – Sebastiano Apr 15 '20 at 09:46
  • 2
    @Sebastiano This is the easy part. I added one possible way to do that. You can adjust the parameters as you like. –  Apr 15 '20 at 15:06
  • 2
    The projection is not entirely correct, see https://tex.stackexchange.com/a/539871/194703. (In my first version of the answer is was, then I thought I had something simpler, but this is wrong. I will try to update this once I have a clever idea on the shading.) –  Apr 24 '20 at 17:43
  • Very kind Schrödinger's cat every improved is always welcome for me. Thus I learn and I see your ideas. My best regards. – Sebastiano Apr 25 '20 at 11:34