TikZ 中的周期势

TikZ 中的周期势

我正在尝试生成此图像:

矢量势

我还没有尝试过这种方法,但似乎没有类似的东西TEXample.net 。有人能指导我如何开始吗?(即我设想沿着 1D 线生成这个不会有问题 - 困难在于环绕线)。

对于方波势而言,期望输出为:

在此处输入图片描述

答案1

是否可以使用 Ti 绘制此图Z?是的,但恕我直言,这要归功于这个精彩的答案Max 所著。让我们祈祷他的这些伟大的例程有一天(很快)能被打包。然而,在此之前,我们必须从他的伟大答案中复制前言。(请注意,我还复制了此版本答案中未使用的部分,该部分涉及“变形”文本,以便让您获得 3D 感觉。我太喜欢这些宏了,以至于不想把它们踢出去。;-)

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usepgfmodule{nonlineartransformations}
\usetikzlibrary{calc}
% Max magic
\makeatletter 
% the first part is not in use here
\def\tikz@scan@transform@one@point#1{%
  \tikz@scan@one@point\pgf@process#1%
  \pgf@pos@transform{\pgf@x}{\pgf@y}}
\tikzset{%
  grid source opposite corners/.code args={#1and#2}{%
   \pgfextract@process\tikz@transform@source@southwest{%
     \tikz@scan@transform@one@point{#1}}%
   \pgfextract@process\tikz@transform@source@northeast{%
     \tikz@scan@transform@one@point{#2}}%
  },
  grid target corners/.code args={#1--#2--#3--#4}{%
   \pgfextract@process\tikz@transform@target@southwest{%
     \tikz@scan@transform@one@point{#1}}%
   \pgfextract@process\tikz@transform@target@southeast{%
     \tikz@scan@transform@one@point{#2}}%
   \pgfextract@process\tikz@transform@target@northeast{%
     \tikz@scan@transform@one@point{#3}}%
   \pgfextract@process\tikz@transform@target@northwest{%
     \tikz@scan@transform@one@point{#4}}%
  }
}

\def\tikzgridtransform{%
  \pgfextract@process\tikz@current@point{}%
  \pgf@process{%
    \pgfpointdiff{\tikz@transform@source@southwest}%
      {\tikz@transform@source@northeast}%
  }%
  \pgf@xc=\pgf@x\pgf@yc=\pgf@y%
  \pgf@process{%
    \pgfpointdiff{\tikz@transform@source@southwest}{\tikz@current@point}%
  }%
  \pgfmathparse{\pgf@x/\pgf@xc}\let\tikz@tx=\pgfmathresult%
  \pgfmathparse{\pgf@y/\pgf@yc}\let\tikz@ty=\pgfmathresult%
  %
  \pgfpointlineattime{\tikz@ty}{%
    \pgfpointlineattime{\tikz@tx}{\tikz@transform@target@southwest}%
      {\tikz@transform@target@southeast}}{%
    \pgfpointlineattime{\tikz@tx}{\tikz@transform@target@northwest}%
      {\tikz@transform@target@northeast}}%
}

% Initialize H matrix for perspective view
\pgfmathsetmacro\H@tpp@aa{1}\pgfmathsetmacro\H@tpp@ab{0}\pgfmathsetmacro\H@tpp@ac{0}%\pgfmathsetmacro\H@tpp@ad{0}
\pgfmathsetmacro\H@tpp@ba{0}\pgfmathsetmacro\H@tpp@bb{1}\pgfmathsetmacro\H@tpp@bc{0}%\pgfmathsetmacro\H@tpp@bd{0}
\pgfmathsetmacro\H@tpp@ca{0}\pgfmathsetmacro\H@tpp@cb{0}\pgfmathsetmacro\H@tpp@cc{1}%\pgfmathsetmacro\H@tpp@cd{0}
\pgfmathsetmacro\H@tpp@da{0}\pgfmathsetmacro\H@tpp@db{0}\pgfmathsetmacro\H@tpp@dc{0}%\pgfmathsetmacro\H@tpp@dd{1}

%Initialize H matrix for main rotation
\pgfmathsetmacro\H@rot@aa{1}\pgfmathsetmacro\H@rot@ab{0}\pgfmathsetmacro\H@rot@ac{0}%\pgfmathsetmacro\H@rot@ad{0}
\pgfmathsetmacro\H@rot@ba{0}\pgfmathsetmacro\H@rot@bb{1}\pgfmathsetmacro\H@rot@bc{0}%\pgfmathsetmacro\H@rot@bd{0}
\pgfmathsetmacro\H@rot@ca{0}\pgfmathsetmacro\H@rot@cb{0}\pgfmathsetmacro\H@rot@cc{1}%\pgfmathsetmacro\H@rot@cd{0}
%\pgfmathsetmacro\H@rot@da{0}\pgfmathsetmacro\H@rot@db{0}\pgfmathsetmacro\H@rot@dc{0}\pgfmathsetmacro\H@rot@dd{1}

\pgfkeys{
    /three point perspective/.cd,
        p/.code args={(#1,#2,#3)}{
            \pgfmathparse{int(round(#1))}
            \ifnum\pgfmathresult=0\else
                \pgfmathsetmacro\H@tpp@ba{#2/#1}
                \pgfmathsetmacro\H@tpp@ca{#3/#1}
                \pgfmathsetmacro\H@tpp@da{ 1/#1}
                \coordinate (vp-p) at (#1,#2,#3);
            \fi
        },
        q/.code args={(#1,#2,#3)}{
            \pgfmathparse{int(round(#2))}
            \ifnum\pgfmathresult=0\else
                \pgfmathsetmacro\H@tpp@ab{#1/#2}
                \pgfmathsetmacro\H@tpp@cb{#3/#2}
                \pgfmathsetmacro\H@tpp@db{ 1/#2}
                \coordinate (vp-q) at (#1,#2,#3);
            \fi
        },
        r/.code args={(#1,#2,#3)}{
            \pgfmathparse{int(round(#3))}
            \ifnum\pgfmathresult=0\else
                \pgfmathsetmacro\H@tpp@ac{#1/#3}
                \pgfmathsetmacro\H@tpp@bc{#2/#3}
                \pgfmathsetmacro\H@tpp@dc{ 1/#3}
                \coordinate (vp-r) at (#1,#2,#3);
            \fi
        },
        coordinate/.code args={#1,#2,#3}{
           \pgfmathsetmacro\tpp@x{#1} %<- Max' fix
            \pgfmathsetmacro\tpp@y{#2}
            \pgfmathsetmacro\tpp@z{#3}
        },
}

\tikzset{
    view/.code 2 args={
        \pgfmathsetmacro\rot@main@theta{#1}
        \pgfmathsetmacro\rot@main@phi{#2}
        % Row 1
        \pgfmathsetmacro\H@rot@aa{cos(\rot@main@phi)}
        \pgfmathsetmacro\H@rot@ab{sin(\rot@main@phi)}
        \pgfmathsetmacro\H@rot@ac{0}
        % Row 2
        \pgfmathsetmacro\H@rot@ba{-cos(\rot@main@theta)*sin(\rot@main@phi)}
        \pgfmathsetmacro\H@rot@bb{cos(\rot@main@phi)*cos(\rot@main@theta)}
        \pgfmathsetmacro\H@rot@bc{sin(\rot@main@theta)}
        % Row 3
        \pgfmathsetmacro\H@m@ca{sin(\rot@main@phi)*sin(\rot@main@theta)}
        \pgfmathsetmacro\H@m@cb{-cos(\rot@main@phi)*sin(\rot@main@theta)}
        \pgfmathsetmacro\H@m@cc{cos(\rot@main@theta)}
        % Set vector values
        \pgfmathsetmacro\vec@x@x{\H@rot@aa}
        \pgfmathsetmacro\vec@y@x{\H@rot@ab}
        \pgfmathsetmacro\vec@z@x{\H@rot@ac}
        \pgfmathsetmacro\vec@x@y{\H@rot@ba}
        \pgfmathsetmacro\vec@y@y{\H@rot@bb}
        \pgfmathsetmacro\vec@z@y{\H@rot@bc}
        % Set pgf vectors
        \pgfsetxvec{\pgfpoint{\vec@x@x cm}{\vec@x@y cm}}
        \pgfsetyvec{\pgfpoint{\vec@y@x cm}{\vec@y@y cm}}
        \pgfsetzvec{\pgfpoint{\vec@z@x cm}{\vec@z@y cm}}
    },
}

\tikzset{
    perspective/.code={\pgfkeys{/three point perspective/.cd,#1}},
    perspective/.default={p={(15,0,0)},q={(0,15,0)},r={(0,0,50)}},
}

\tikzdeclarecoordinatesystem{three point perspective}{
    \pgfkeys{/three point perspective/.cd,coordinate={#1}}
    \pgfmathsetmacro\temp@p@w{\H@tpp@da*\tpp@x + \H@tpp@db*\tpp@y + \H@tpp@dc*\tpp@z + 1}
    \pgfmathsetmacro\temp@p@x{(\H@tpp@aa*\tpp@x + \H@tpp@ab*\tpp@y + \H@tpp@ac*\tpp@z)/\temp@p@w}
    \pgfmathsetmacro\temp@p@y{(\H@tpp@ba*\tpp@x + \H@tpp@bb*\tpp@y + \H@tpp@bc*\tpp@z)/\temp@p@w}
    \pgfmathsetmacro\temp@p@z{(\H@tpp@ca*\tpp@x + \H@tpp@cb*\tpp@y + \H@tpp@cc*\tpp@z)/\temp@p@w}
    \pgfpointxyz{\temp@p@x}{\temp@p@y}{\temp@p@z}
}
\tikzaliascoordinatesystem{tpp}{three point perspective}

\makeatother


\begin{document}
\tdplotsetmaincoords{80}{-20}
\begin{tikzpicture}[scale=pi,%tdplot_main_coords
  view={\tdplotmaintheta}{\tdplotmainphi},
            perspective={
                p = {(5,0,0.5)},
                q = {(0,4,0.5)},
            },
  declare function={potential(\x)=-0.0314*pow(abs(\x),2);}          
  ]
  \draw[thick] plot[variable=\x,domain=0:360,samples=37,smooth] 
  (tpp cs:{cos(\x)},{sin(\x)},0);
  \pgfmathsetmacro{\Nion}{40}
  \pgfmathsetmacro{\Dist}{360/\Nion}
  \pgfmathsetmacro{\xmin}{1}
  \pgfmathsetmacro{\xmax}{\Dist-\xmin}
  \draw[-latex] (tpp cs:0,-1,0) -- (tpp cs:0,-1,{1.2*potential(\xmin-\Dist/2)})
  node[right]{$V$};
  \draw[-latex] plot[variable=\x,domain=0:\Dist,samples={\Dist+1},smooth] 
  (tpp  cs:{cos(-90+\x)},{sin(-90+\x)},{-0.2*potential(\xmin-\Dist/2)});
  \node[anchor=south] at (tpp  cs:{cos(-90+\Dist/2)},{sin(-90+\Dist/2)},{-0.22*potential(\xmin-\Dist/2)})
  {$x$};
  \foreach \index in {1,...,\Nion}
   {\draw plot[variable=\x,domain=\xmin:\xmax,samples={\Dist+1},smooth] 
  (tpp
  cs:{cos(\x+\index*\Dist)},{sin(\x+\index*\Dist)},{potential(\x-\Dist/2)});
  \fill let \p1=($(tpp cs:{cos(\index*\Dist)},{sin(\index*\Dist)},2)-
  (tpp cs:{cos(\index*\Dist)},{sin(\index*\Dist)},0)$),\n1={veclen(\x1,\y1)}
  in
  (tpp cs:{cos(\index*\Dist)},{sin(\index*\Dist)},0) circle(\n1*0.01pt);
    }
\end{tikzpicture}
\end{document}

在此处输入图片描述

  1. 关键的perspective确切功能在Max 的精彩回答,在我看来,它值得更多点赞。但请注意,如果您过多地更改圆的半径,那么您可能还需要增加透视点的坐标pq以避免division by zero出现问题。
  2. 势能的定义是declare function={potential(\x)=-0.0314*pow(abs(\x),2);}
  3. 离子的数量由 设定\pgfmathsetmacro{\Nion}{40}
  4. 由于您的上部屏幕截图中存在间隙,因此我添加了一个控制间隙宽度的参数:\pgfmathsetmacro{\xmin}{1}。这意味着间隙2*\xmin=2宽度为 度。

如果你保留上面的序言,但将文档更改为(请注意,我backgrounds现在也加载了库)

\usetikzlibrary{backgrounds}
\begin{document}
\tdplotsetmaincoords{80}{-20}
\begin{tikzpicture}[scale=pi,%tdplot_main_coords
      view={\tdplotmaintheta}{\tdplotmainphi},
                perspective={
                    p = {(5,0,0.5)},
                    q = {(0,4,0.5)},
                },
      declare function={potential(\x)=ifthenelse(abs(\x)<\Dist/4,0,-0.6);}          
      ]
      \draw[thick] plot[variable=\x,domain=0:360,samples=37,smooth] 
      (tpp cs:{cos(\x)},{sin(\x)},0);
      \pgfmathsetmacro{\Nion}{40}
      \pgfmathsetmacro{\Dist}{360/\Nion}
      \pgfmathsetmacro{\xmin}{0}
      \pgfmathsetmacro{\xmax}{\Dist-\xmin}
      \draw[-latex] (tpp cs:0,-1,0) -- (tpp cs:0,-1,{1.2*potential(\xmin-\Dist/2)})
      node[right]{$V$};
      \draw[-latex] plot[variable=\x,domain=0:\Dist,samples={\Dist+1},smooth] 
      (tpp  cs:{cos(-90+\x)},{sin(-90+\x)},{-0.2*potential(\xmin-\Dist/2)});
      \node[anchor=south] at (tpp  cs:{cos(-90+\Dist/2)},{sin(-90+\Dist/2)},{-0.22*potential(\xmin-\Dist/2)})
      {$x$};
      \foreach \index in {1,...,\Nion}
       {\begin{scope}[on background layer]
       \draw[thick,blue] plot[variable=\x,domain=\xmin:\xmax,samples={29}] 
      (tpp
      cs:{cos(\x+\index*\Dist)},{sin(\x+\index*\Dist)},{potential(\x-\Dist/2)});
      \end{scope}
      \fill let \p1=($(tpp cs:{cos(\index*\Dist)},{sin(\index*\Dist)},2)-
  (tpp cs:{cos(\index*\Dist)},{sin(\index*\Dist)},0)$),\n1={veclen(\x1,\y1)}
  in
  (tpp cs:{cos(\index*\Dist)},{sin(\index*\Dist)},0) circle(\n1*0.01pt);
        }
    \end{tikzpicture}
\end{document}

在此处输入图片描述

(这里的潜在线并不是完全垂直的,但如果增加,则几乎会变得更加垂直sample。您可以通过用适当的线条组合替换图来更改这一点,如果您需要帮助,请告诉我。)

更新:使离子的直径也依赖于距离,以增强 3D 效果。

相关内容