我正在尝试生成此图像:
我还没有尝试过这种方法,但似乎没有类似的东西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}
- 关键的
perspective
确切功能在Max 的精彩回答,在我看来,它值得更多点赞。但请注意,如果您过多地更改圆的半径,那么您可能还需要增加透视点的坐标p
,q
以避免division by zero
出现问题。 - 势能的定义是
declare function={potential(\x)=-0.0314*pow(abs(\x),2);}
。 - 离子的数量由 设定
\pgfmathsetmacro{\Nion}{40}
。 - 由于您的上部屏幕截图中存在间隙,因此我添加了一个控制间隙宽度的参数:
\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 效果。