球形(锥形)箭头

球形(锥形)箭头

转至第 81 页渐近线教程有球形箭头提示:

在此处输入图片描述 在此处输入图片描述

我喜欢第一幅图和第二幅图箭头的提示,Arrow3()它也可以用于 2D。这个提示只存在于渐近线中,还是也存在于TikZpstricks或特定符号或包中?

答案1

这只是为了好玩。关于在屏幕上投影 3d 锥体的一些考虑。主要目的是解释为什么我认为来自尖端的极值射线一般与从投影底面圆到屏幕上而出现的椭圆的切线有关。锥体的投影是一个三角形。可以通过分析计算锥体与底面的交点来获得

\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}

在此处输入图片描述

这可以用来构造箭头。阴影是从这里

\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}

在此处输入图片描述

这可以按照通常的方式用来创建符号。

\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}

在此处输入图片描述

相关内容