如果我在 tikz 中绘制线圈,我通常会执行以下操作:
\documentclass[tikz]{standalone}
\usetikzlibrary{decorations.pathmorphing,patterns}
\begin{document}
\begin{tikzpicture}
\draw[decoration={aspect=0.3, segment length=3.2mm, amplitude=3mm,coil},decorate,opacity=0.9] (1,0) -- (3,0);
\end{tikzpicture}
\end{document}
看起来像这样:
在某些情况下(例如在电动力学中),线圈是右手还是左手可能很重要。
我怎样才能修改上面的代码,使它看起来像这样:
如果您有其他可能更好的方法来形象化我感兴趣的方向。
答案1
所有这些的起点是 中的代码pgflibrarydecorations.pathmorphing.code.tex
。我承认 joojaa 的评论指出光环在原始答案中不太正确。我也很感谢 Robert Harvey 的评论,他鼓励我进行清理。我所做的是修改图书馆coil
的装饰decorations.pathmorphing
。还有很大的改进空间。开头的键允许您调整颜色、不透明度、线圈宽度和光环的额外宽度,我希望我给这些参数起的名字是不言自明的。
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{decorations.pathmorphing}
\pgfkeys{%
/pgf/decoration/.cd,
3d coil color/.store in=\TDCoilColor,
3d coil color/.initial=black,
3d coil color=black,
3d coil width/.store in=\TDCoilWidth,
3d coil width/.initial=0.4pt,
3d coil width=0.4pt,
3d coil dist/.store in=\TDCoilDist,
3d coil dist/.initial=0.6pt,
3d coil dist=0.6pt,
3d coil opacity/.store in=\TDCoilOpacity,
3d coil opacity/.initial=1,
3d coil opacity=1
}
\makeatletter % https://tex.stackexchange.com/a/219088/121799
\tikzset{get stroke color/.code={%
\expandafter\global% Jump over, now we have \global
\expandafter\let% Jump over now we have \global\let
\expandafter\pgfsavedstrokecolor% Jump we have \global\let\pgf...
\csname\string\color@pgfstrokecolor\endcsname% Finally expand this and put it at the end
}, % \global\let\pgf...{} in expanded form
restore stroke color/.code={\pgf@setstrokecolor#1},
}
\def\pgfpoint@onthreedcoil#1#2#3{%
\pgf@x=#1\pgfdecorationsegmentamplitude%
\pgf@x=\pgfdecorationsegmentaspect\pgf@x%
\pgf@y=#2\pgfdecorationsegmentamplitude%
\pgf@xa=0.083333333333\pgfdecorationsegmentlength%
\advance\pgf@x by#3\pgf@xa%
\advance\pgf@x by-\initialoffset pt%
}
% coil decoration
%
% Parameters: \pgfdecorationsegmentamplitude, \pgfdecorationsegmentlength,
\pgfdeclaredecoration{3d coil}{initial}
{
\state{initial}[width=0.25*\pgfdecorationsegmentlength+\pgfdecorationsegmentaspect*\pgfdecorationsegmentamplitude,
next state=coil, persistent precomputation={
\tikzset{get stroke color}
\pgfmathsetmacro{\initialoffset}{0.25*\pgfdecorationsegmentlength+\pgfdecorationsegmentaspect*\pgfdecorationsegmentamplitude}
}]
{%
\pgfpathmoveto{\pgfpointorigin}
\pgfsetstrokecolor{\TDCoilColor}
\pgfsetstrokeopacity{\TDCoilOpacity}
\pgfsetlinewidth{1.5*\TDCoilWidth}
\pgfpathcurveto
{\pgfpoint@oncoil{0 }{ 0.555}{1}}
{\pgfpoint@oncoil{0.445}{ 1 }{2}}
{\pgfpoint@oncoil{1 }{ 1 }{3}}
\pgfusepath{stroke}
\pgfcoordinate{TD@coilast}{\pgfpoint@oncoil{1 }{ 1 }{3}}
}
\state{coil}[switch if less than=%
1.25\pgfdecorationsegmentlength+%
\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude+%
\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude to last,
width=+\pgfdecorationsegmentlength]
{ % line in the back
%
\pgfsetstrokecolor{\TDCoilColor}
\pgfsetfillcolor{\TDCoilColor}
\pgfsetstrokeopacity{\TDCoilOpacity}
\pgfpathmoveto{\pgfpointanchor{TD@coilast}{center}}
\pgfsetlinewidth{\TDCoilWidth}
\pgfpathcurveto
{\pgfpoint@onthreedcoil{1.555}{ 1 }{4}}
{\pgfpoint@onthreedcoil{2 }{ 0.555}{5}}
{\pgfpoint@onthreedcoil{2 }{ 0 }{6}}
\pgfpathcurveto
{\pgfpoint@onthreedcoil{2 }{-0.555}{7}}
{\pgfpoint@onthreedcoil{1.555}{-1 }{8}}
{\pgfpoint@onthreedcoil{1 }{-1 }{9}}
\pgfusepath{stroke}
%
% white background for front thick part
%
\pgfsetstrokeopacity{1}
\pgfsetstrokecolor{white}
\pgfsetfillcolor{white}
\pgfsetlinewidth{1.5*\TDCoilWidth+1.5*\TDCoilDist}
\pgfpathmoveto{\pgfpoint@onthreedcoil{1 }{ 1 }{3}}
\pgfpathmoveto{\pgfpoint@onthreedcoil{1 }{-1 }{9}}
% draw forward
\pgfpathcurveto
{\pgfpoint@onthreedcoil{0.445}{-1 }{10}}
{\pgfpoint@onthreedcoil{0 }{-0.555}{11.25}}
{\pgfpoint@onthreedcoil{0 }{ 0 }{12.5}}
\pgfpathcurveto
{\pgfpoint@onthreedcoil{0 }{ 0.555}{13.25}}
{\pgfpoint@onthreedcoil{0.445}{ 1 }{14.25}}
{\pgfpoint@onthreedcoil{1 }{ 1 }{15}}
% draw the curve back
\pgfpathcurveto
{\pgfpoint@onthreedcoil{0.445}{ 1 }{14}}
{\pgfpoint@onthreedcoil{0 }{ 0.555}{12.75}}
{\pgfpoint@onthreedcoil{0 }{ 0 }{11.5}}
\pgfpathcurveto
{\pgfpoint@onthreedcoil{0 }{-0.555}{10.75}}
{\pgfpoint@onthreedcoil{0.445}{-1 }{10}}
{\pgfpoint@onthreedcoil{1 }{-1 }{9}}
\pgfusepath{stroke,fill}
%
% draw the thick foreground path
%
\pgfsetstrokecolor{\TDCoilColor}
\pgfsetfillcolor{\TDCoilColor}
\pgfsetstrokeopacity{\TDCoilOpacity}
\pgfpathmoveto{\pgfpoint@onthreedcoil{1 }{ 1 }{3}}
\pgfsetlinewidth{\TDCoilWidth}
% forward shifted +
\pgfpathmoveto{\pgfpoint@onthreedcoil{1 }{-1 }{9}}
\pgfpathcurveto
{\pgfpoint@onthreedcoil{0.445}{-1 }{10}}
{\pgfpoint@onthreedcoil{0 }{-0.555}{11.25}}
{\pgfpoint@onthreedcoil{0 }{ 0 }{12.5}}
\pgfpathcurveto
{\pgfpoint@onthreedcoil{0 }{ 0.555}{13.25}}
{\pgfpoint@onthreedcoil{0.445}{ 1 }{14.25}}
{\pgfpoint@onthreedcoil{1 }{ 1 }{15}}
% draw the curve back shfted -
\pgfpathcurveto
{\pgfpoint@onthreedcoil{0.445}{ 1 }{14}}
{\pgfpoint@onthreedcoil{0 }{ 0.555}{12.75}}
{\pgfpoint@onthreedcoil{0 }{ 0 }{11.5}}
\pgfpathcurveto
{\pgfpoint@onthreedcoil{0 }{-0.555}{10.75}}
{\pgfpoint@onthreedcoil{0.445}{-1 }{10}}
{\pgfpoint@onthreedcoil{1 }{-1 }{9}}
\pgfusepath{stroke,fill} % <- added
\pgfcoordinate{TD@coilast}{\pgfpoint@onthreedcoil{1 }{ 1 }{15}}
}
\state{last}[width=.25\pgfdecorationsegmentlength+%
\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude+%
\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude,next state=final]
{
\pgfsetstrokecolor{\TDCoilColor}
\pgfsetstrokeopacity{\TDCoilOpacity}
\pgfsetlinewidth{\TDCoilWidth}
\pgfpathmoveto{\pgfpointanchor{TD@coilast}{center}}
\pgfpathcurveto
{\pgfpoint@onthreedcoil{1.555}{ 1 }{4}}
{\pgfpoint@onthreedcoil{2 }{ 0.555}{5}}
{\pgfpoint@onthreedcoil{2 }{ 0 }{6}}
}
\state{final}
{
\pgfpathlineto{\pgfpointdecoratedpathlast}
\pgfusepath{stroke}
\tikzset{restore stroke color/.expand once=\pgfsavedstrokecolor}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw[decoration={3d coil color=blue,aspect=0.35, segment length=3.1mm, amplitude=3mm,3d coil},
decorate] (0,0) -- (0,3);
\draw[decoration={3d coil color=red,3d coil opacity=0.9,aspect=0.45, segment length=3.1mm, amplitude=3mm,3d coil},
decorate] (2,3) -- (2,0);
\draw[decoration={3d coil color=green!60!black,3d coil opacity=0.9,aspect=0.35, segment length=3.1mm, amplitude=3mm,3d coil},
decorate] (4,3) to[out=0,in=90] (6,0);
\end{tikzpicture}
\end{document}
乐趣:强制动画可以用相同的前言+\usepackage{tikzmarmots}
和
\begin{document}
\foreach \X [evaluate=\X as \Y using {sin(\X)}]in {0,10,...,350}
{
\begin{tikzpicture}
\path[use as bounding box] (-1,-0.2) rectangle (1,4);
\draw[decoration={3d coil color=blue,aspect=0.35, segment
length={(1.2+0.7*\Y)*1mm}, amplitude=3mm,3d coil},
decorate] (0,0) -- (0,2);
\begin{scope}[shift={(-0.9,1+0.5*\Y)}]
\marmot[teeth,whiskers]
\end{scope}
\end{tikzpicture}}
\end{document}
答案2
aspect
如果将和设置为负值amplitude
,则可以得到镜像线圈,在@marmot 的答案中添加这一项可能会完成所需的输出;此外,我还添加了一个选项,使用标记来获得一些类似的绘图,该绘图使用范围和yscale
反转标记,然后使用一个新变量来控制线圈颜色,当路径为直时效果很好,标记路径缺乏弯曲效果较好。
编辑:增加了标记步骤的控制以改善弯曲结果。
结果:
梅威瑟:
\documentclass[tikz,border=20pt]{standalone}
\usetikzlibrary{decorations.pathmorphing,decorations.markings}
\begin{document}
\begin{tikzpicture}[
CoilColor/.store in=\coilcolor,CoilColor=black,
Step/.store in=\Step,Step=0.1,
Coil/.style={
double=black,
draw=gray!50,
decoration={
#1,
segment length=3mm,
coil
},
decorate,
},
Coil2/.style={
decorate,
decoration={
markings,
mark= between positions 0 and 1 step \Step
with {
\begin{scope}[yscale=#1]
\draw[xshift=9.2,fill,\coilcolor!70!black]
(0,0)++(-135: 0.2 and 0.4)
.. controls +(-0.2,0) and +(-0.3,0) .. (90: 0.2 and 0.4)
.. controls +(-0.33,0) and +(-0.23,0) .. (-135: 0.2 and 0.4);
\draw[white,line width=2pt]
(0,0)++(90: 0.2 and 0.4)
.. controls +(0.3,0) and +(0.2,0) .. (-45: 0.2 and 0.4);
\draw[fill=\coilcolor,\coilcolor]
(0,0)++(90: 0.2 and 0.4)
.. controls +(0.3,0) and +(0.2,0) .. (-45: 0.2 and 0.4)
.. controls +(0.25,0) and +(0.35,0) .. (90: 0.2 and 0.4);
\end{scope}
}
}
}
]
\draw[Coil={aspect=-0.3,amplitude=-3mm},blue] (0,0) -- ++ (0,-3);
\draw[Coil={aspect=0.3,amplitude=3mm},red] (1.5,0) -- ++ (0,-3);
\draw[Coil={aspect=0.3,amplitude=3mm},green!50!black] (3,0) arc (90:0:3);
\draw[Coil={aspect=-0.3,amplitude=-3mm}] (3,1) arc (90:0:4);
\draw[Coil2=-1,CoilColor=blue] (0,-4) -- ++ (0,-3);
\draw[Coil2=1,CoilColor=red] (1.5,-4) -- ++ (0,-3);
\draw[Coil2=-1,CoilColor=green!50!black,Step=0.065] (3,-4) arc (90:0:3);
\draw[Coil2=1,Step=0.048] (3,-3) arc (90:0:4);
\end{tikzpicture}
\end{document}
更新:根据@marmot 的建议,使用, 来弥补差距并绘制所有变化\pgfdecoratedpathlength
。/pgf/decoration/mark info/sequence number
梅威瑟:
\documentclass[tikz,border=20pt]{standalone}
\usetikzlibrary{decorations.markings}
\begin{document}
\begin{tikzpicture}[
CoilColor/.store in=\coilcolor,CoilColor=black,
Step/.store in=\Step,Step=0.1,
Width/.store in=\Width,Width=0.4,
Coil2/.style={
decorate,
decoration={
markings,
mark= between positions 0 and 1 step \Step
with {
\begin{scope}[yscale=#1]
\pgfmathparse{int(\pgfdecoratedpathlength/28.45*100*\Step)}
\edef\Hight{\pgfmathresult}
\ifnum\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}=1
\path (0,0)++(90: \Hight/200 and \Width) coordinate (b);
\fi
\ifnum\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}>1
\coordinate (b) at (d);
\fi
\path (b) arc (90:-135: \Hight/200 and \Width) coordinate (a);
\path (b) arc (90:-45: \Hight/200 and \Width) coordinate (c);
\path (b)++(\Hight/100,0) coordinate (d);
\draw[fill,\coilcolor!70!black]
(c)
.. controls +(-0.175,0) and +(-0.275,0) .. (d)
.. controls +(-0.325,0) and +(-0.225,0) .. (c);
\draw[white,line width=2pt]
(b)
.. controls +(0.3,0) and +(0.2,0) .. (c);
\draw[fill,\coilcolor]
(b)
.. controls +(0.275,0) and +(0.175,0) .. (c)
.. controls +(0.225,0) and +(0.325,0) .. (b);
\end{scope}
}
}
}
]
\draw[Coil2=-1,CoilColor=red,Step=0.15] (0.5,0) -- ++ (0,-3);
\draw[Coil2=1.5,CoilColor=magenta] (1.5,0) -- ++ (0,-3);
\draw[Coil2=1,CoilColor=green!70!black,Step=0.02] (0,-4)
to [in=90,out=0] ++(2.5,-1)
to [in=180,out=-90] ++(2.5,-1)
to [in=-90,out=0] ++(2,1.5)
to [in=-90,out=90] ++(0.5,3) arc (0:90:2);
\draw[Coil2=-1,CoilColor=green!50!cyan,Step=0.02] (0,-5)
to [in=90,out=0] ++(1.5,-1)
to [in=180,out=-90] ++(4,-1)
to [in=-90,out=0] ++(3,2.5)
to [in=-90,out=90] ++(0.5,4.5) arc (0:90:2);
\draw[Coil2=1,CoilColor=cyan!30!blue,Step=0.05] (5.7,-2) arc (360:0:1.5);
\draw[Coil2=-1,CoilColor=cyan!70!blue,Step=0.05] (6.5,-2) arc (360:0:1.5);
\end{tikzpicture}
\end{document}