\documentclass[border=5mm,tikz]{standalone}
\usetikzlibrary{decorations.pathmorphing,patterns}
\begin{document}
\begin{tikzpicture}
\pgfmathsetmacro{\cubex}{1}
\pgfmathsetmacro{\cubey}{3}
\pgfmathsetmacro{\cubez}{.71}
\draw[red,fill=yellow] (0,0,0) -- ++(-\cubex,0,0) -- ++(0,-\cubey,0) -- ++(\cubex,0,0) -- cycle;
\draw[red,fill=yellow] (0,0,0) -- ++(0,0,-\cubez) -- ++(0,-\cubey,0) -- ++(0,0,\cubez) -- cycle;
\draw[red,fill=yellow] (0,0,0) -- ++(-\cubex,0,0) -- ++(0,0,-\cubez) -- ++(\cubex,0,0) -- cycle;
\draw[decoration={aspect=.3523, segment length=.6060285mm, amplitude=1.616mm,coil},decorate] (-.35,1.52) -- (-.35,0.4);
\draw(-.35,1.52)--(-.35,1.8);
\draw(-.35,.18)--(-.35,.4);
\draw[decoration={aspect=.3523, segment length=.6060285mm, amplitude=1.616mm,coil},decorate] (-.35,-3.52) -- (-.35,-4.4);
\draw(-.35,-3.52)--(-.35,-3);
\draw(-.35,-4.4)--(-.35,-4.654);
\end{tikzpicture}
\end{document}
答案1
我假设问题在于让线圈缠绕在磁铁上。解决方案如下:https://tex.stackexchange.com/a/43605/8650(由我)。
\documentclass[border=5mm,tikz]{standalone}
\usetikzlibrary{decorations.pathmorphing,patterns}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}
\makeatletter
% Decorations based on
% https://tex.stackexchange.com/questions/32297/modify-tikz-coil-decoration/43605#43605
% coilup decoration
%
% Parameters: \pgfdecorationsegmentamplitude, \pgfdecorationsegmentlength,
\pgfdeclaredecoration{coilup}{coil}
{
\state{coil}[switch if less than=%
1.5\pgfdecorationsegmentlength+%
\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude+%
\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude to last,
width=+\pgfdecorationsegmentlength]
{
\pgfpathcurveto
{\pgfpoint@oncoil{0 }{ 0.555}{1}}
{\pgfpoint@oncoil{0.445}{ 1 }{2}}
{\pgfpoint@oncoil{1 }{ 1 }{3}}
\pgfpathmoveto{\pgfpoint@oncoil{1 }{-1 }{9}}
\pgfpathcurveto
{\pgfpoint@oncoil{0.445}{-1 }{10}}
{\pgfpoint@oncoil{0 }{-0.555}{11}}
{\pgfpoint@oncoil{0 }{ 0 }{12}}
}
\state{last}[width=.5\pgfdecorationsegmentlength+%
\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude+%
\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude,next state=final]
{
\pgfpathcurveto
{\pgfpoint@oncoil{0 }{ 0.555}{1}}
{\pgfpoint@oncoil{0.445}{ 1 }{2}}
{\pgfpoint@oncoil{1 }{ 1 }{3}}
\pgfpathmoveto{\pgfpoint@oncoil{1 }{ 1 }{3}}
% Uncomment the following lines to close the last loop
% \pgfpathcurveto
% {\pgfpoint@oncoil{1.555}{ 1 }{4}}
% {\pgfpoint@oncoil{2 }{ 0.555}{5}}
% {\pgfpoint@oncoil{2 }{ 0 }{6}}
% \pgfpathcurveto
% {\pgfpoint@oncoil{2 }{-0.555}{7}}
% {\pgfpoint@oncoil{1.555}{-1 }{8}}
% {\pgfpoint@oncoil{0 }{-1 }{9}}
}
\state{final}
{
\pgfpathmoveto{\pgfpointdecoratedpathlast}
}
}
% coildown decoration
%
% Parameters: \pgfdecorationsegmentamplitude, \pgfdecorationsegmentlength,
\pgfdeclaredecoration{coildown}{coil}
{
\state{coil}[switch if less than=%
1.5\pgfdecorationsegmentlength+%
\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude+%
\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude to last,
width=+\pgfdecorationsegmentlength]
{
\pgfpathmoveto{\pgfpoint@oncoil{1 }{1 }{3}}
\pgfpathcurveto
{\pgfpoint@oncoil{1.555}{ 1 }{4}}
{\pgfpoint@oncoil{2 }{ 0.555}{5}}
{\pgfpoint@oncoil{2 }{ 0 }{6}}
\pgfpathcurveto
{\pgfpoint@oncoil{2 }{-0.555}{7}}
{\pgfpoint@oncoil{1.555}{-1 }{8}}
{\pgfpoint@oncoil{1 }{-1 }{9}}
}
\state{last}[width=.5\pgfdecorationsegmentlength+%
\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude+%
\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude,next state=final]
{
% Comment the next 5 lines when closing the last loop
\pgfpathmoveto{\pgfpoint@oncoil{1 }{ 1 }{3}}
\pgfpathcurveto
{\pgfpoint@oncoil{1.555}{ 1 }{4}}
{\pgfpoint@oncoil{2 }{ 0.555}{5}}
{\pgfpoint@oncoil{2 }{ 0 }{6}}
}
\state{final}
{}
}
\def\pgfpoint@oncoil#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%
}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw[decoration={aspect=0.1, segment length=2, amplitude=20 mm, coilup},decorate] (-0.2,-1) -- (-0.2,-2);
\pgfmathsetmacro{\cubex}{1}
\pgfmathsetmacro{\cubey}{3}
\pgfmathsetmacro{\cubez}{.71}
\draw[red,fill=yellow] (0,0,0) -- ++(-\cubex,0,0) -- ++(0,-\cubey,0) -- ++(\cubex,0,0) -- cycle;
\draw[red,fill=yellow] (0,0,0) -- ++(0,0,-\cubez) -- ++(0,-\cubey,0) -- ++(0,0,\cubez) -- cycle;
\draw[red,fill=yellow] (0,0,0) -- ++(-\cubex,0,0) -- ++(0,0,-\cubez) -- ++(\cubex,0,0) -- cycle;
\draw[decoration={aspect=0.1, segment length=2, amplitude=20 mm, coildown},decorate] (-0.2,-1) -- (-0.2,-2);
\draw[decoration={aspect=.3523, segment length=.6060285mm, amplitude=1.616mm,coil},decorate] (-.35,1.52) -- (-.35,0.4);
\draw(-.35,1.52)--(-.35,1.8);
\draw(-.35,.18)--(-.35,.4);
\draw[decoration={aspect=.3523, segment length=.6060285mm, amplitude=1.616mm,coil},decorate] (-.35,-3.52) -- (-.35,-4.4);
\draw(-.35,-3.52)--(-.35,-3);
\draw(-.35,-4.4)--(-.35,-4.654);
\end{tikzpicture}
\end{document}
请注意,\makeatletter
和之间的所有内容都\makeatother
只是为了使coilup
和coildown
工作。其余部分并不比您自己的代码更复杂。
答案2
这是一份提案,下面有更多解释和动画。除了从终端到螺旋的垂直线外,大多数元素都已包含。这是因为我不理解它们,即不知道这些是 3D 图片的元素还是只是一些垂直线。
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{calc,3d,decorations.pathmorphing}
\makeatletter % https://tex.stackexchange.com/a/48776/121799
\tikzoption{canvas is xy plane at z}[]{%
\def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
\def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
\def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
\tikz@canvas@is@plane
}
\makeatother
\pgfkeys{plane scale/.store in=\PlaneScale,
plane scale=1}
\newcommand{\DrawPlane}[4][]{
\draw[canvas is #2,#1]
({-0.5*\PlaneScale*#3},{-0.5*\PlaneScale*#4}) rectangle
({0.5*\PlaneScale*#3},{0.5*\PlaneScale*#4});
}
\newcommand{\DrawSinglePlane}[2][]{
\ifcase#2
\or
\pgfmathtruncatemacro{\myint}{60+40*cos(\tdplotmaintheta)}
\DrawPlane[fill=blue!\myint,#1]{xy plane at z=-\cubez/2}{\cubex}{\cubey} % 1st xy plane
\or
\pgfmathtruncatemacro{\myint}{60+40*cos(\tdplotmaintheta)}
\DrawPlane[fill=blue!\myint,#1]{xy plane at z=\cubez/2}{\cubex}{\cubey} % 2nd xy plane
\or
\pgfmathtruncatemacro{\myint}{60+40*abs(cos(\tdplotmainphi))}
\DrawPlane[fill=blue!\myint,#1]{xz plane at y=-\cubey/2}{\cubex}{\cubez} % 1st xz plane
\or
\pgfmathtruncatemacro{\myint}{60+40*abs(cos(\tdplotmainphi))}
\DrawPlane[fill=blue!\myint,#1]{xz plane at y=\cubey/2}{\cubex}{\cubez} % 2nd xz plane
\or
\pgfmathtruncatemacro{\myint}{60+40*abs(sin(\tdplotmainphi))}
\DrawPlane[fill=blue!\myint,#1]{yz plane at x=-\cubex/2}{\cubey}{\cubez} % 1sy uz plane
\or
\pgfmathtruncatemacro{\myint}{60+40*abs(sin(\tdplotmainphi))}
\DrawPlane[fill=blue!\myint,#1]{yz plane at x=\cubex/2}{\cubey}{\cubez} % 2nd uz plane
\fi
}
\begin{document}
\tdplotsetmaincoords{70}{60} % the first argument cannot be larger than 90
\begin{tikzpicture}[font=\sffamily]
\pgfmathsetmacro{\cubex}{1}
\pgfmathsetmacro{\cubey}{.71}
\pgfmathsetmacro{\cubez}{3}
\pgfmathsetmacro{\R}{1.2}
\begin{scope}[tdplot_main_coords]
% \draw[thick,->] (0,0,0) -- (2,0,0) node[anchor=north east]{$x$};
% \draw[thick,->] (0,0,0) -- (0,2,0) node[anchor=north west]{$y$};
% \draw[thick,->] (0,0,0) -- (0,0,1.5) node[anchor=south]{$z$};
\path let \p1=(1,0,0) in
\pgfextra{\pgfmathtruncatemacro{\xproj}{sign(\x1)}\xdef\xproj{\xproj}};
\pgfmathtruncatemacro{\zproj}{sign(cos(\tdplotmaintheta))}
%\xdef\zproj{\zproj}
% \node[anchor=north west] at (current bounding box.north west)
% {\tdplotmaintheta,\tdplotmainphi,\zproj,\xproj};
%
% lower spiral
\draw (0,0,-4) coordinate (bottom) -- plot[variable=\x,domain=\tdplotmainphi+270:\tdplotmainphi+360]
({0.2*\R*cos(\x)},{0.2*\R*sin(\x)},{0.1*(\x/360-31)});
\foreach \Y in {-30,-29,...,-20}
{\draw plot[variable=\x,domain=\tdplotmainphi:\tdplotmainphi+360]
({0.2*\R*cos(\x)},{0.2*\R*sin(\x)},{0.1*(\x/360+\Y)});}
\draw plot[variable=\x,domain=\tdplotmainphi:\tdplotmainphi+90]
({0.2*\R*cos(\x)},{0.2*\R*sin(\x)},{0.1*(\x/360-19)})
-- (0,0,-\cubez/2);
% big spiral in the back
\foreach \Y in {-5,...,5}
{\draw plot[variable=\x,domain=\tdplotmainphi:\tdplotmainphi+180]
({\R*cos(\x)},{\R*sin(\x)},{0.1*(\x/360+\Y)});}
% cube
\foreach \X in {3,6,2}
{\DrawSinglePlane{\X}}
\begin{scope}[canvas is yz plane at x=\cubex/2]
\coordinate (plane) at (0,-0.4*\cubez);
\end{scope}
% big spiral in the front
\foreach \Y in {-5,...,5}
{\draw plot[variable=\x,domain=\tdplotmainphi+180:\tdplotmainphi+360]
({\R*cos(\x)},{\R*sin(\x)},{0.1*(\x/360+\Y)});}
% upper spiral
\draw (0,0,\cubez/2) -- plot[variable=\x,domain=\tdplotmainphi+270:\tdplotmainphi+360]
({0.2*\R*cos(\x)},{0.2*\R*sin(\x)},{0.1*(\x/360+19)});
\foreach \Y in {20,21,...,30}
{\draw plot[variable=\x,domain=\tdplotmainphi:\tdplotmainphi+360]
({0.2*\R*cos(\x)},{0.2*\R*sin(\x)},{0.1*(\x/360+\Y)});}
\draw plot[variable=\x,domain=\tdplotmainphi:\tdplotmainphi+90]
({0.2*\R*cos(\x)},{0.2*\R*sin(\x)},{0.1*(\x/360+31)})
-- (0,0,4) coordinate (top);
% coords
\path ({0.2*\R*cos(\tdplotmainphi+180)},{0.2*\R*sin(\tdplotmainphi+180)},{2.5})
coordinate (spring)
({\R*cos(\tdplotmainphi+230)},{\R*sin(\tdplotmainphi+230)},{0.1*230/360}) coordinate (coil)
({\R*cos(\tdplotmainphi)},{\R*sin(\tdplotmainphi)},{0}) coordinate (right)
({\R*cos(\tdplotmainphi+180)},{\R*sin(\tdplotmainphi+180)},{0}) coordinate (left);
\end{scope}
\draw (left |- bottom) rectangle (right |- top);
\path (top -| left) -- (top -| right) node[fill,inner sep=3pt,above=0pt,pos=0.2] (L){}
node[fill,inner sep=3pt,above=0pt,pos=0.8] (R){};
\draw (L) -- ++ (0,1) -| node[circle,draw,pos=0.25,fill=white]{A} (R);
\draw (spring) -- ++ (-2.5,0) node[left](spring) {spring};
\draw (coil) -- ++ (-2.5,0);
\node[anchor=west,fill=white] at (spring.west |- coil) {coil};
\draw (R) -- ++ (1.5,0) node[right] (terminal) {terminal};
\begin{scope}
\clip[rounded corners]
([xshift=-2.8cm]bottom -| left) -- ([xshift=2.8cm]bottom -| right)
|- ++ (-2,-2) -| cycle;
\draw[fill=gray!30,decoration={random steps,segment length=2mm}]
([xshift=-3cm,yshift=-4mm]bottom -| left) [decorate]-- ([xshift=3cm,yshift=-4mm]bottom -|
right) |- ++ (-2,-2) -| cycle;
\end{scope}
\path (bottom -| left) -- (bottom -| right)
coordinate[midway,yshift=-1cm] (aux0)
coordinate[midway,yshift=-1.7cm] (aux1)
coordinate[pos=0.4,yshift=-2mm] (aux2)
coordinate[pos=0.6,yshift=-2mm] (aux3);
\draw[fill=gray] (bottom -| left) |- (aux2)
-- (aux1) -- (aux3) -| (bottom -| right);
\draw (aux0) -- ++ (3,0);
\node[anchor=west,fill=white,align=left] at (terminal.west |- aux0) {spike in\\
ground};
\draw (plane) -- ++ (3,0);
\node[anchor=west,fill=white,align=left] at (terminal.west |- plane)
{oscillating\\ magnet};
\end{tikzpicture}
\end{document}
这只是为了好玩。原则上,你可以使用 pgfplots 来实现这一点。我专注于立方体和螺旋。
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16,width=8cm}
\begin{document}
\begin{tikzpicture}[declare function={spiralz(\x,\y)=\x/360+\y;}]
\pgfmathsetmacro{\cubex}{1}
\pgfmathsetmacro{\cubey}{.71}
\pgfmathsetmacro{\cubez}{3}
\pgfmathsetmacro{\R}{2}
\begin{axis}[hide axis,view={40}{35},set layers,
cube/size x=\cubex cm,cube/size y=\cubey cm,cube/size z=\cubez cm]
\pgfplotsinvokeforeach{1,...,10}{
\addplot3[domain=\pgfkeysvalueof{/pgfplots/view/az}:{\pgfkeysvalueof{/pgfplots/view/az}+180},mesh,point meta=x,color=black,
on layer=axis background] ({\R*cos(x)},{\R*sin(x)},{2*spiralz(x,#1)});
}
\addplot3 [only marks,mark=cube*,mark size=7,
on layer=pre main,color=yellow] coordinates {(0,0,10)};
\pgfplotsinvokeforeach{1,...,10}{
\addplot3[domain={\pgfkeysvalueof{/pgfplots/view/az}+180}:{\pgfkeysvalueof{/pgfplots/view/az}+360},mesh,point meta=x,color=black,
on layer=axis foreground] ({\R*cos(x)},{\R*sin(x)},{2*spiralz(x,#1)});
}
%\typeout{\pgfkeysvalueof{/pgfplots/view/az},\pgfkeysvalueof{/pgfplots/view/el}}
\end{axis}
\end{tikzpicture}
\end{document}
这样做的好处是,您有正交投影,并且可以调整视图。缺点是编译时间。
为了加快速度,可以使用tikz-3dplot
,这需要区分 4 种情况(在此动画中)。
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{calc,3d}
\makeatletter % https://tex.stackexchange.com/a/48776/121799
\tikzoption{canvas is xy plane at z}[]{%
\def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
\def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
\def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
\tikz@canvas@is@plane
}
\makeatother
\pgfkeys{plane scale/.store in=\PlaneScale,
plane scale=1}
\newcommand{\DrawPlane}[4][]{
\draw[canvas is #2,#1]
({-0.5*\PlaneScale*#3},{-0.5*\PlaneScale*#4}) rectangle
({0.5*\PlaneScale*#3},{0.5*\PlaneScale*#4});
}
\newcommand{\DrawSinglePlane}[2][]{
\ifcase#2
\or
\pgfmathtruncatemacro{\myint}{60+40*cos(\tdplotmaintheta)}
\DrawPlane[fill=blue!\myint,#1]{xy plane at z=-\cubez/2}{\cubex}{\cubey} % 1st xy plane
\or
\pgfmathtruncatemacro{\myint}{60+40*cos(\tdplotmaintheta)}
\DrawPlane[fill=blue!\myint,#1]{xy plane at z=\cubez/2}{\cubex}{\cubey} % 2nd xy plane
\or
\pgfmathtruncatemacro{\myint}{60+40*abs(cos(\tdplotmainphi))}
\DrawPlane[fill=blue!\myint,#1]{xz plane at y=-\cubey/2}{\cubex}{\cubez} % 1st xz plane
\or
\pgfmathtruncatemacro{\myint}{60+40*abs(cos(\tdplotmainphi))}
\DrawPlane[fill=blue!\myint,#1]{xz plane at y=\cubey/2}{\cubex}{\cubez} % 2nd xz plane
\or
\pgfmathtruncatemacro{\myint}{60+40*abs(sin(\tdplotmainphi))}
\DrawPlane[fill=blue!\myint,#1]{yz plane at x=-\cubex/2}{\cubey}{\cubez} % 1sy uz plane
\or
\pgfmathtruncatemacro{\myint}{60+40*abs(sin(\tdplotmainphi))}
\DrawPlane[fill=blue!\myint,#1]{yz plane at x=\cubex/2}{\cubey}{\cubez} % 2nd uz plane
\fi
}
\begin{document}
\foreach \X in {0,5,...,355}
{\tdplotsetmaincoords{90-40*sin(\X)}{\X} % the first argument cannot be larger than 90
\begin{tikzpicture}
\pgfmathsetmacro{\cubex}{1}
\pgfmathsetmacro{\cubey}{.71}
\pgfmathsetmacro{\cubez}{3}
\pgfmathsetmacro{\R}{1.2}
\path[use as bounding box] (-2*\R,-2.4*\R) rectangle (2*\R,2.4*\R);
\begin{scope}[tdplot_main_coords]
% \draw[thick,->] (0,0,0) -- (2,0,0) node[anchor=north east]{$x$};
% \draw[thick,->] (0,0,0) -- (0,2,0) node[anchor=north west]{$y$};
% \draw[thick,->] (0,0,0) -- (0,0,1.5) node[anchor=south]{$z$};
\path let \p1=(1,0,0) in
\pgfextra{\pgfmathtruncatemacro{\xproj}{sign(\x1)}\xdef\xproj{\xproj}};
\pgfmathtruncatemacro{\zproj}{sign(cos(\tdplotmaintheta))}
%\xdef\zproj{\zproj}
% \node[anchor=north west] at (current bounding box.north west)
% {\tdplotmaintheta,\tdplotmainphi,\zproj,\xproj};
\ifnum\zproj=1
\foreach \Y in {-5,...,5}
{\draw plot[variable=\x,domain=\tdplotmainphi:\tdplotmainphi+180]
({\R*cos(\x)},{\R*sin(\x)},{0.1*(\x/360+\Y)});}
\else
\foreach \Y in {-5,...,5}
{\draw plot[variable=\x,domain=\tdplotmainphi+180:\tdplotmainphi+360]
({\R*cos(\x)},{\R*sin(\x)},{0.1*(\x/360+\Y)});}
\fi
\ifnum\zproj=1
\ifnum\xproj=1
\foreach \XX in {2,3,6}
{\DrawSinglePlane{\XX}}
\else
\foreach \XX in {4,6,2}
{\DrawSinglePlane{\XX}}
\fi
\else
\ifnum\xproj=1
\foreach \XX in {2,4,6}
{\DrawSinglePlane{\XX}}
\else
\foreach \XX in {3,6,2}
{\DrawSinglePlane{\XX}}
\fi
\fi
\ifnum\zproj=1
\foreach \Y in {-5,...,5}
{\foreach \Y in {-5,...,5}
{\draw plot[variable=\x,domain=\tdplotmainphi+180:\tdplotmainphi+360]
({\R*cos(\x)},{\R*sin(\x)},{0.1*(\x/360+\Y)});}
}
\else
\foreach \Y in {-5,...,5}
{\draw plot[variable=\x,domain=\tdplotmainphi:\tdplotmainphi+180]
({\R*cos(\x)},{\R*sin(\x)},{0.1*(\x/360+\Y)});}
\fi
\end{scope}
\end{tikzpicture}}
\end{document}