我想在 Ti 中绘制类似下面的内容钾Z,但不幸的是,我不知道如何得到所需的结果。该图显示了四极杆质谱仪中离子的路径。在四极杆(那 4 根杆)外部,没有电磁场作用于离子,因此它们沿直线飞行。如果它们进入四极杆,它们可以与电磁场产生共振,从而处于圆柱形螺旋路径上,也可以不产生共振,从而处于圆锥形螺旋路径上,迟早会从侧面离开四极杆。
我对这个问题的解决方法是使用3D 图绘制螺旋线,其中有圆锥图和圆柱图pgfplots
函数。不幸的是,我发现自己无法解决以下问题:{x*cos(deg(x))},{x*sin(deg(x)},{x}
{cos(deg(x))},{sin(deg(x)},{x}
- 正确定位螺旋
- 画一条直线,在离开四极杆后变成螺旋线,然后回到直线(仅适用于圆柱形)
- 在路径退出四极杆后不久停止锥形螺旋
我很清楚这有很多问题,因此我很高兴得到任何提示。
我目前的(糟糕的)尝试
\documentclass{standalone}
\usepackage{xparse}
\usepackage{ifthen}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.markings}
\begin{document}
\begin{tikzpicture}
% General constants
% %%%%%%%%%%%%%%%%%
\coordinate (msOrigin) at (0,0);
\pgfmathsetmacro{\msY}{3}
\pgfmathsetmacro{\offsetX}{0.3}
\pgfmathsetmacro{\offsetY}{0.2}
\pgfmathsetmacro{\spacer}{0.75}
\pgfmathsetmacro{\arrowLength}{1}
\pgfmathsetmacro{\centerOffset}{0.3}
% Quadrupole constants
% %%%%%%%%%%%%%%%%%%%%
\pgfmathsetmacro{\quadrupoleRadiusHorizontal}{0.08}
\pgfmathsetmacro{\quadrupoleRadiusVertical}{0.2}
\pgfmathsetmacro{\quadrupoleLength}{3}
\pgfmathsetmacro{\quadrupolePathLength}{\quadrupoleLength - (2 * \quadrupoleRadiusHorizontal)}
\pgfmathsetmacro{\quadrupoleTopFrontY}{0.5 * \msY + \centerOffset + 2 * \quadrupoleRadiusVertical}
\pgfmathsetmacro{\quadrupoleTopBackY}{\quadrupoleTopFrontY + \offsetY}
\pgfmathsetmacro{\quadrupoleBottomBackY}{0.5 * \msY - \centerOffset}
\pgfmathsetmacro{\quadrupoleBottomFrontY}{\quadrupoleBottomBackY - \offsetY}
\NewDocumentCommand{\cylinder}{m m m m m m m m}{% coordX, coordY, length, radiusX, radiusY, colorCylinder, colorEllipse, opacity
\fill [#6, fill opacity = #8]
($ (msOrigin) + ({#1},{#2}) $)
--
++({#3},0)
arc
(90:270:-{#4} and {#5})
--
++(-{#3},0)
arc
(270:90:-{#4} and {#5});
\draw [fill = #7, fill opacity = #8]
($ (msOrigin) + ({#1},{#2}) + (0,{-#5}) $)
ellipse
({#4} and {#5});
\draw
($ (msOrigin) + ({#1},{#2}) $)
--
++({#3},0)
arc
(90:270:-{#4} and {#5})
--
++(-{#3},0);
}
\NewDocumentCommand{\quadrupoleRod}{m m m}{% segment, top/bottom, front/back
\ifthenelse{\equal{#2}{top} \AND \equal{#3}{front}}{%
\pgfmathsetmacro{\coordX}{\quadrupoleRadiusHorizontal + \offsetX}
\pgfmathsetmacro{\coordY}{\quadrupoleTopFrontY}
}{}
\ifthenelse{\equal{#2}{top} \AND \equal{#3}{back}}{%
\pgfmathsetmacro{\coordX}{\quadrupoleRadiusHorizontal}
\pgfmathsetmacro{\coordY}{\quadrupoleTopBackY}
}{}
\ifthenelse{\equal{#2}{bottom} \AND \equal{#3}{front}}{%
\pgfmathsetmacro{\coordX}{\quadrupoleRadiusHorizontal + \offsetX}
\pgfmathsetmacro{\coordY}{\quadrupoleBottomFrontY}
}{}
\ifthenelse{\equal{#2}{bottom} \AND \equal{#3}{back}}{%
\pgfmathsetmacro{\coordX}{\quadrupoleRadiusHorizontal}
\pgfmathsetmacro{\coordY}{\quadrupoleBottomBackY}
}{}
\cylinder
{\coordX}
{\coordY}
{\quadrupolePathLength}
{\quadrupoleRadiusHorizontal}
{\quadrupoleRadiusVertical}
{gray}
{white}
{1}
}
\NewDocumentCommand{\quadrupolePair}{m m}{% segment, front/back
\ifthenelse{\equal{#2}{front} \OR \equal{#2}{back}}{%
\quadrupoleRod{#1}{top}{#2}
\quadrupoleRod{#1}{bottom}{#2}
}{}
}
\quadrupolePair{1}{back}
\begin{axis}[
rotate around={-90:(current axis.origin)},
view = {30}{20},
axis line style = {draw = none},
tick style = {draw = none},
zmax = 60,
xtick=\empty,
ytick=\empty,
ztick=\empty
]
\addplot3+[
mark = none,
thick,
red,
domain = 0:50*pi,
samples = 1000,
samples y = 0,
]
% ({x*cos(deg(x))},{x*sin(deg(x)},{x});
({cos(deg(x))},{sin(deg(x)},{x});
\end{axis}
\quadrupolePair{1}{front}
\end{tikzpicture}
\end{document}
更新 2020-11-26
我发现这个答案在 TeX.SX 上帮助绘制圆柱形线圈。通过一些修改,我能够在这个过程中取得相对较大进展。剩下的一个问题是连接水平路径和螺旋的线,因为代码mark=at position #1 with \coordinate (#2);
会抛出Dimension too large.
错误,即使我不明白为什么。线圈很小,绝对低于 19 英尺……
剩下的另一个问题是圆锥螺旋。我有一个起点,但不幸的是,它看起来很恶心。
\documentclass{standalone}
\usepackage{xparse}
\usepackage{ifthen}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.markings}
\tikzset{
mark position/.style args={#1(#2)}{
postaction={
decorate,
decoration={
markings,
mark=at position #1 with \coordinate (#2);
}
}
}
}
\NewDocumentCommand{\cylinder}{m m m m m m m m}{% coordX, coordY, length, radiusX, radiusY, colorCylinder, colorEllipse, opacity
\fill [#6, fill opacity = #8]
($ (msOrigin) + ({#1},{#2}) $)
--
++({#3},0)
arc
(90:270:-{#4} and {#5})
--
++(-{#3},0)
arc
(270:90:-{#4} and {#5});
\draw [fill = #7, fill opacity = #8]
($ (msOrigin) + ({#1},{#2}) + (0,{-#5}) $)
ellipse
({#4} and {#5});
\draw
($ (msOrigin) + ({#1},{#2}) $)
--
++({#3},0)
arc
(90:270:-{#4} and {#5})
--
++(-{#3},0);
}
\NewDocumentCommand{\quadrupoleRod}{m m m}{% segment, top/bottom, front/back
\ifthenelse{\equal{#2}{top} \AND \equal{#3}{front}}{%
\pgfmathsetmacro{\coordX}{\quadrupoleRadiusHorizontal + \offsetX}
\pgfmathsetmacro{\coordY}{\quadrupoleTopFrontY}
}{}
\ifthenelse{\equal{#2}{top} \AND \equal{#3}{back}}{%
\pgfmathsetmacro{\coordX}{\quadrupoleRadiusHorizontal}
\pgfmathsetmacro{\coordY}{\quadrupoleTopBackY}
}{}
\ifthenelse{\equal{#2}{bottom} \AND \equal{#3}{front}}{%
\pgfmathsetmacro{\coordX}{\quadrupoleRadiusHorizontal + \offsetX}
\pgfmathsetmacro{\coordY}{\quadrupoleBottomFrontY}
}{}
\ifthenelse{\equal{#2}{bottom} \AND \equal{#3}{back}}{%
\pgfmathsetmacro{\coordX}{\quadrupoleRadiusHorizontal}
\pgfmathsetmacro{\coordY}{\quadrupoleBottomBackY}
}{}
\cylinder
{\coordX}
{\coordY}
{\quadrupolePathLength}
{\quadrupoleRadiusHorizontal}
{\quadrupoleRadiusVertical}
{gray}
{white}
{1}
}
\NewDocumentCommand{\quadrupolePair}{m m}{% segment, front/back
\ifthenelse{\equal{#2}{front} \OR \equal{#2}{back}}{%
\quadrupoleRod{#1}{top}{#2}
\quadrupoleRod{#1}{bottom}{#2}
}{}
}
\begin{document}
% General constants
% %%%%%%%%%%%%%%%%%
\pgfmathsetmacro{\offsetX}{0.5}
\pgfmathsetmacro{\offsetY}{0.6}
\pgfmathsetmacro{\spacer}{0.75}
\pgfmathsetmacro{\centerOffset}{0.3}
% Quadrupole constants
% %%%%%%%%%%%%%%%%%%%%
\pgfmathsetmacro{\quadrupoleRadiusHorizontal}{0.08}
\pgfmathsetmacro{\quadrupoleRadiusVertical}{0.2}
\pgfmathsetmacro{\quadrupoleLength}{4}
\pgfmathsetmacro{\quadrupolePathLength}{\quadrupoleLength - (2 * \quadrupoleRadiusHorizontal)}
\pgfmathsetmacro{\quadrupoleTopFrontY}{\centerOffset + 2 * \quadrupoleRadiusVertical}
\pgfmathsetmacro{\quadrupoleTopBackY}{\quadrupoleTopFrontY + \offsetY}
\pgfmathsetmacro{\quadrupoleBottomBackY}{-\centerOffset}
\pgfmathsetmacro{\quadrupoleBottomFrontY}{\quadrupoleBottomBackY - \offsetY}
\begin{tikzpicture}
\coordinate (msOrigin) at (0,0);
% Define a formula for the coil.
% This is what the numbers mean:
% 0.25: the x offset
% 0.13: how far the rings are apart
% 0.30: how much from the side the rings are seen
% 0.75: radius of the rings
\def\coil#1{
{0.25 + 0.13 * (2 * #1 + \t) + 0.30 * sin(- \t * pi r))},
{0.75 * cos(-\t * pi r)}
}
% Draw the background-rods
\quadrupolePair{1}{back}
% Draw the part of the coil behind
\foreach \n in {1,...,14} {
\draw[domain={0:1},smooth,variable=\t,samples=15]
plot (\coil{\n});
}
% Draw the part of the coil in front
\foreach \n in {0,1,...,13} {
\ifthenelse{\equal{\n}{0} \OR \equal{\n}{13}}
{%
\ifthenelse{\equal{\n}{0}}{%
\draw[
domain = {1:2},
smooth,
variable = \t,
samples = 15,
% mark position = 0(start)
]
plot (\coil{\n});
}{%
\draw[
domain = {1:2},
smooth,
variable = \t,
samples = 15,
% mark position = 1(end)
]
plot (\coil{\n});
}
}{
\draw[
domain = {1:2},
smooth,
variable = \t,
samples = 15
]
plot (\coil{\n});
}
}
% Draw the foreground-rods
\quadrupolePair{1}{front}
\draw
% (start) % to join the mark position "start"
(0.25, -0.75)
to [out = 180, in = 0]
++(-1, 0.75);
\draw
% (end) % to join the mark position "end"
(4, -0.75)
to [out = 0, in = 180]
++(1, 0.75);
\end{tikzpicture}
\hspace{1em}
\begin{tikzpicture}
\coordinate (msOrigin) at (0,0);
% Define a formula for the coil.
% This is what the numbers mean:
% 0.25: the x offset
% 0.13: how far the rings are apart
% 0.30: how much from the side the rings are seen
% 0.75: radius of the rings
\def\coil#1{
{0.25 + 0.13 * (2 * #1 + \t) + 0.30 * sin(- \t * pi r)},
{0.75 * #1/10 * \t * cos(-\t * pi r)}
}
% Draw the background-rods
\quadrupolePair{1}{back}
% Draw the part of the coil behind
\foreach \n in {1,...,14} {
\draw[domain={0:1},smooth,variable=\t,samples=15]
plot (\coil{\n});
}
% Draw the part of the coil in front
\foreach \n in {0,1,...,13} {
\ifthenelse{\equal{\n}{0} \OR \equal{\n}{13}}
{%
\ifthenelse{\equal{\n}{0}}{%
\draw[
domain = {1:2},
smooth,
variable = \t,
samples = 15,
% mark position = 0(start)
]
plot (\coil{\n});
}{%
\draw[
domain = {1:2},
smooth,
variable = \t,
samples = 15,
% mark position = 1(end)
]
plot (\coil{\n});
}
}{
\draw[
domain = {1:2},
smooth,
variable = \t,
samples = 15
]
plot (\coil{\n});
}
}
% Draw the foreground-rods
\quadrupolePair{1}{front}
\end{tikzpicture}
\end{document}
答案1
我认为没有必要使用 PGF 代码 - 只要注意到可以用 绘制螺旋线,您就几乎知道了{cos(deg(x))},{sin(deg(x)},{x}
。我通常喜欢 PGFPlots,但这不是绘图(轴、刻度、刻度、标签……)。我相信plot
TikZ 中的函数是正确的方法。
为了拉直螺旋线的末端,我让振幅与线圈的螺距同时衰减。我不确定你想让圆锥线如何结束 - 一个简单的方法就是让线圈的振幅快速上升并调整域。
\documentclass[tikz, border=1cm]{standalone}
\begin{document}
\begin{tikzpicture}[ultra thick]
\newcommand{\domA}{-pi}
\newcommand{\domB}{0}
\newcommand{\domC}{2*pi}
\newcommand{\domD}{4*pi}
\newcommand{\domE}{\domC+0.5}
\newcommand{\pitch}{10}
\newcommand{\ampA}{(1/(1+\domB-\x))}
\newcommand{\ampB}{(1/(1-\domC+\x))}
\newcommand{\ampC}{(0.1*(\x-\domB)+1)}
\draw[red, domain={\domA:\domB}, smooth, samples=100] plot (\x, {\ampA*cos((\ampA*\pitch*\x+(1-\ampA)*\pitch*\domB) r)}, {\ampA*sin((\ampA*\pitch*\x+(1-\ampA)*\pitch*\domB) r)} );
\draw[green, domain={\domB:\domC}, smooth, samples=200] plot (\x, {cos(\pitch*\x r)} , {sin(\pitch*\x r)} );
\draw[blue, domain={\domC:\domD}, smooth, samples=100] plot (\x, {\ampB*cos((\ampB*\pitch*\x+(1-\ampB)*\pitch*\domC) r)}, {\ampB*sin((\ampB*\pitch*\x+(1-\ampB)*\pitch*\domC) r)} );
\begin{scope}[yshift=-4cm]
\draw[teal, domain={\domA:\domB}, smooth, samples=100] plot (\x, {cos((\ampA*\pitch*\x+(1-\ampA)*\pitch*\domB) r)}, {sin((\ampA*\pitch*\x+(1-\ampA)*\pitch*\domB) r)} );
\draw[orange, domain={\domB:\domC}, smooth, samples=200] plot (\x, {\ampC*cos(\pitch*\x r)} , {\ampC*sin(\pitch*\x r)} );
\draw[violet, domain={\domC:\domE}, smooth, samples=100] plot (\x, {\ampC*1/\ampB*cos(\pitch*\x r)} , {\ampC*1/\ampB*sin(\pitch*\x r)} );
\end{scope}
\end{tikzpicture}
\end{document}
编辑:
TikZ 中的默认 z 向量指向 (−3.85mm, −3.85mm)。要更改视角,你可以使用例如z={(-3.85mm, 3.85mm)}
:
\documentclass[tikz, border=1cm]{standalone}
\begin{document}
\begin{tikzpicture}[z={(-3.85mm, 3.85mm)}]
\newcommand{\domA}{-pi}
\newcommand{\domB}{0}
\newcommand{\domC}{2*pi}
\newcommand{\domD}{4*pi}
\newcommand{\domE}{\domC+0.5}
\newcommand{\pitch}{10}
\newcommand{\ampA}{(1/(1+\domB-\x))}
\newcommand{\ampB}{(1/(1-\domC+\x))}
\newcommand{\ampC}{(0.1*(\x-\domB)+1)}
\draw[fill=gray] (-1,1.2,1) -- (7,1.2,1) arc[start angle=90, end angle=-90, x radius=0.1cm, y radius=0.2cm] -- (-1,0.8,1);
\draw[fill=white](-1,1,1) circle[x radius=0.1cm, y radius=0.2cm];
\draw[fill=gray] (-1,-1.2,1) -- (7,-1.2,1) arc[start angle=-90, end angle=90, x radius=0.1cm, y radius=0.2cm] -- (-1,-0.8,1);
\draw[fill=white](-1,-1,1) circle[x radius=0.1cm, y radius=0.2cm];
\draw[red, thick, domain={\domA:\domB}, smooth, samples=100] plot (\x, {\ampA*cos((\ampA*\pitch*\x+(1-\ampA)*\pitch*\domB) r)}, {\ampA*sin((\ampA*\pitch*\x+(1-\ampA)*\pitch*\domB) r)} );
\draw[red, thick, domain={\domB:\domC}, smooth, samples=200] plot (\x, {cos(\pitch*\x r)} , {sin(\pitch*\x r)} );
\draw[red, thick, domain={\domC:\domD}, smooth, samples=100] plot (\x, {\ampB*cos((\ampB*\pitch*\x+(1-\ampB)*\pitch*\domC) r)}, {\ampB*sin((\ampB*\pitch*\x+(1-\ampB)*\pitch*\domC) r)} );
\draw[fill=gray] (-1,1.2,-1) -- (7,1.2,-1) arc[start angle=90, end angle=-90, x radius=0.1cm, y radius=0.2cm] -- (-1,0.8,-1);
\draw[fill=white](-1,1,-1) circle[x radius=0.1cm, y radius=0.2cm];
\draw[fill=gray] (-1,-1.2,-1) -- (7,-1.2,-1) arc[start angle=-90, end angle=90, x radius=0.1cm, y radius=0.2cm] -- (-1,-0.8,-1);
\draw[fill=white](-1,-1,-1) circle[x radius=0.1cm, y radius=0.2cm];
\end{tikzpicture}
\end{document}
红色螺旋中的扭结是因为它smooth
在不同的图上不起作用。我可以看到两种纠正方法:要么删除该smooth
选项,要么大幅增加样本。-或者更好:使用 TikZdeclare function
声明分段函数,然后只执行一阴谋。