summaryrefslogtreecommitdiff
path: root/graphics/pgf/contrib/tikz-3dtools/tikzlibrary3dtools.code.tex
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/pgf/contrib/tikz-3dtools/tikzlibrary3dtools.code.tex')
-rw-r--r--graphics/pgf/contrib/tikz-3dtools/tikzlibrary3dtools.code.tex712
1 files changed, 712 insertions, 0 deletions
diff --git a/graphics/pgf/contrib/tikz-3dtools/tikzlibrary3dtools.code.tex b/graphics/pgf/contrib/tikz-3dtools/tikzlibrary3dtools.code.tex
new file mode 100644
index 0000000000..fd29370c81
--- /dev/null
+++ b/graphics/pgf/contrib/tikz-3dtools/tikzlibrary3dtools.code.tex
@@ -0,0 +1,712 @@
+% Copyright 2019 by an anonymous marmot
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+\ProvidesFileRCS{tikzlibrary3dtools.code.tex}
+\usetikzlibrary{3d,decorations,fpu}% to do: ability to switch on and off
+\usepackage{calculator}% maybe drop
+\makeatletter%
+\def\extractpgfversionaux#1.#2.#3|#4#5#6;{\def#4{#1}\def#5{#2}\def#6{#3}}%
+\def\checkversion{%
+\edef\temp{\noexpand\extractpgfversionaux\pgfversion|\noexpand\myu\noexpand\myv\noexpand\myw;}%
+\temp%
+\pgfmathtruncatemacro{\itest}{ifthenelse(10*\myu+\myv<31,0,1)}%
+\ifnum\itest=0%
+\message{You are using a too old version of pgf (\pgfversion). You need at least
+version 3.1.1 to use the features of this library.}%
+\fi}%
+\checkversion%
+\newcommand{\orthmat}[3]{% the entries of this matrix keep track
+\pgfmathparse{cos(#1)*cos(#2)}% of the current transformation
+\xdef\tikz@td@matAA{\pgfmathresult}%
+\pgfmathparse{cos(#2)*sin(#1)}%
+\xdef\tikz@td@matAB{\pgfmathresult}%
+\pgfmathparse{sin(#2)}%
+\xdef\tikz@td@matAC{\pgfmathresult}%
+\pgfmathparse{-cos(#3)*sin(#1)-cos(#1)*sin(#2)*sin(#3)}%
+\xdef\tikz@td@matBA{\pgfmathresult}%
+\pgfmathparse{cos(#1)*cos(#3)-sin(#1)*sin(#2)*sin (#3)}%
+\xdef\tikz@td@matBB{\pgfmathresult}%
+\pgfmathparse{cos(#2)*sin (#3)}%
+\xdef\tikz@td@matBC{\pgfmathresult}%
+\pgfmathparse{sin(#1)*sin(#3)-cos(#1)*cos(#3)*sin(#2)}%
+\xdef\tikz@td@matCA{\pgfmathresult}%
+\pgfmathparse{-cos(#3)*sin(#1)*sin(#2)-cos(#1)*sin(#3)}%
+\xdef\tikz@td@matCB{\pgfmathresult}%
+\pgfmathparse{cos(#2)*cos(#3)}%
+\xdef\tikz@td@matCC{\pgfmathresult}}%
+\tikzset{3d/.cd,phi/.initial=0,psi/.initial=0,theta/.initial=0,
+install view/.style={/utils/exec=\tikzset{3d/.cd,#1}%
+\orthmat{\pgfkeysvalueof{/tikz/3d/phi}}{%
+\pgfkeysvalueof{/tikz/3d/psi}}{\pgfkeysvalueof{/tikz/3d/theta}},%
+/tikz/x={({\tikz@td@matAA*1cm},{\tikz@td@matBA*1cm})},%
+/tikz/y={({\tikz@td@matAB*1cm},{\tikz@td@matBB*1cm})},%
+/tikz/z={({\tikz@td@matAC*1cm},{\tikz@td@matBC*1cm})}}}%
+\def\pgfmathparse@td@FPU#1{\begingroup%
+\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
+\pgfmathparse{#1}%
+\pgfmathsmuggle\pgfmathresult\endgroup}%
+%
+\newlength\pgf@X% not clear if one should use lengths here at all
+\newlength\pgf@Y%
+\newlength\pgf@Z%
+\newlength\pgf@Xa%
+\newlength\pgf@Ya%
+\newlength\pgf@Za%
+\newlength\pgf@Xb%
+\newlength\pgf@Yb%
+\newlength\pgf@Zb%
+\xdef\tikz@td@type{0}%0=linear combination,1=vector product
+\long\def\RawCoord(#1){\csname tikz@dcl@coord@#1\endcsname}%
+\long\def\ParseCoord(#1){%
+\pgfutil@tempcnta=0%
+\pgfutil@for\pgf@tmp:={#1}\do{\advance\pgfutil@tempcnta by1}%
+\ifnum\the\pgfutil@tempcnta=1
+\edef\pgfutil@tmp{\csname tikz@dcl@coord@#1\endcsname}%
+\else%
+\edef\pgfutil@tmp{(#1)}%
+\fi%
+\pgfmathparse@td@FPU{xcomp3(\pgfutil@tmp)}%
+\pgf@X=\pgfmathresult pt%
+\pgfmathparse@td@FPU{ycomp3(\pgfutil@tmp)}%
+\pgf@Y=\pgfmathresult pt%
+\pgfmathparse@td@FPU{zcomp3(\pgfutil@tmp)}%
+\pgf@Z=\pgfmathresult pt}%
+\pgfmathdeclarefunction{TD}{1}{%
+\begingroup%
+\pgfmathtdparse{#1}%
+\pgfmathsmuggle\pgfmathresult\endgroup%
+}%
+% projections
+\pgfmathdeclarefunction{xcomp3}{3}{% x component of a 3-vector
+\begingroup%
+\pgfmathparse@td@FPU{#1}%
+\pgfmathsmuggle\pgfmathresult\endgroup}
+\pgfmathdeclarefunction{ycomp3}{3}{% y component of a 3-vector
+\begingroup%
+\pgfmathparse@td@FPU{#2}%
+\pgfmathsmuggle\pgfmathresult\endgroup}
+\pgfmathdeclarefunction{zcomp3}{3}{% z component of a 3-vector
+\begingroup%
+\pgfmathparse@td@FPU{#3}%
+\pgfmathsmuggle\pgfmathresult\endgroup}
+\pgfmathdeclarefunction{TDx}{1}{% x component of a 3-vector
+\begingroup%
+\edef\mycoord{\RawCoord(#1)}%
+\pgfmathparse@td@FPU{xcomp3\mycoord}%
+\pgfmathsmuggle\pgfmathresult\endgroup}%
+\pgfmathdeclarefunction{TDy}{1}{% x component of a 3-vector
+\begingroup%
+\edef\mycoord{\RawCoord(#1)}%
+\pgfmathparse@td@FPU{ycomp3\mycoord}%
+\pgfmathsmuggle\pgfmathresult\endgroup}%
+\pgfmathdeclarefunction{TDz}{1}{% x component of a 3-vector
+\begingroup%
+\edef\mycoord{\RawCoord(#1)}%
+\pgfmathparse@td@FPU{zcomp3\mycoord}%
+\pgfmathsmuggle\pgfmathresult\endgroup}%
+\def\scalprod#1=#2.#3;{%
+\edef\coordA{\RawCoord#2}%
+\edef\coordB{\RawCoord#3}%
+\pgfmathsetmacro\pgfutil@tmpa{scalarproduct({\coordA},{\coordB})}%
+\edef#1{\pgfutil@tmpa}}%
+\def\spaux#1#2#3#4#5#6{(#1)*(#4)+(#2)*(#5)+(#3)*(#6)}%
+\pgfmathdeclarefunction{scalarproduct}{2}{% scalar product of two 3-vectors
+\begingroup%
+\pgfmathparse@td@FPU{\spaux#1#2}%
+\pgfmathsmuggle\pgfmathresult\endgroup}
+% vector product
+% vector product auxiliary functions
+\def\vpauxx#1#2#3#4#5#6{(#2)*(#6)-(#3)*(#5)}%
+\def\vpauxy#1#2#3#4#5#6{(#4)*(#3)-(#1)*(#6)}%
+\def\vpauxz#1#2#3#4#5#6{(#1)*(#5)-(#2)*(#4)}%
+% vector product pgf functions
+\pgfmathdeclarefunction{vpx}{2}{% x component of vector product
+\begingroup%
+\pgfmathparse@td@FPU{\vpauxx#1#2}%
+\pgfmathsmuggle\pgfmathresult\endgroup}
+\pgfmathdeclarefunction{vpy}{2}{% y component of vector product
+\begingroup%
+\pgfmathparse@td@FPU{\vpauxy#1#2}%
+\pgfmathsmuggle\pgfmathresult\endgroup}
+\pgfmathdeclarefunction{vpz}{2}{% z component of vector product
+\begingroup%
+\pgfmathparse@td@FPU{\vpauxz#1#2}%
+\pgfmathsmuggle\pgfmathresult\endgroup}
+%
+%
+% the following is very much "inspired" by the calc library
+\long\def\pgfmathtdparse#1{% < and > really are placeholders for a later integration
+\begingroup% into calc, which however requires changes both in
+% tikzlibrarycalc.code.tex and in tikz.code.tex
+%
+% tdparse main computation. It's a series of optional factors in front
+% of coordinates. It is very much copied from the calc library.
+%
+\pgf@Xa=0pt% We accumulate the result in here.
+\pgf@Ya=0pt%
+\pgf@Za=0pt%
+\tikz@td@cc@parse+#1%
+}%
+
+\def\tikz@td@cc@parse{%
+\pgfutil@ifnextchar>{%
+% Ok, we found the end...
+\tikz@td@cc@end%
+}
+{\pgfutil@ifnextchar+{%
+% Ok, we found a coordinate...
+\tikz@td@cc@add%
+}{%
+\pgfutil@ifnextchar-{%
+\tikz@td@cc@sub%
+}{%
+\pgfutil@ifnextchar x{%
+\tikz@td@cc@vecprod%
+}{%
+\pgfutil@ifnextchar o{%
+\tikz@td@cc@scalprod%
+}{% \tikzerror{+ or - expected}%
+\tikz@td@cc@end%
+}%
+}%
+}%
+}%
+}%
+}%
+%
+% The end is reached with > at the moment but this should change
+%
+\def\tikz@td@cc@end{%
+\ifcase\tikz@td@type%
+\pgfmathsetmacro{\pgftemp@x}{\pgf@Xa}%
+\pgfmathsetmacro{\pgftemp@y}{\pgf@Ya}%
+\pgfmathsetmacro{\pgftemp@z}{\pgf@Za}%
+\edef\pgfmathresult{\pgftemp@x,\pgftemp@y,\pgftemp@z}%
+\or%
+\pgfmathsetmacro{\myxa}{\pgf@Xa}%
+\pgfmathsetmacro{\myya}{\pgf@Ya}%
+\pgfmathsetmacro{\myza}{\pgf@Za}%
+\pgfmathsetmacro{\myxb}{\pgf@Xb}%
+\pgfmathsetmacro{\myyb}{\pgf@Yb}%
+\pgfmathsetmacro{\myzb}{\pgf@Zb}%
+\pgfmathsetmacro{\pgftemp@x}{\vpauxx{\myxb}{\myyb}{\myzb}{\myxa}{\myya}{\myza}}%
+\pgfmathsetmacro{\pgftemp@y}{\vpauxy{\myxb}{\myyb}{\myzb}{\myxa}{\myya}{\myza}}%
+\pgfmathsetmacro{\pgftemp@z}{\vpauxz{\myxb}{\myyb}{\myzb}{\myxa}{\myya}{\myza}}%
+%\typeout{P1=(\myxb,\myyb,\myzb),P2=(\myxa,\myya,\myza),P1xP2=(\pgftemp@x,\pgftemp@y,\pgftemp@z)}%
+\edef\pgfmathresult{\pgftemp@x,\pgftemp@y,\pgftemp@z}%
+\or%
+\pgfmathsetmacro{\myxa}{\pgf@Xa}%
+\pgfmathsetmacro{\myya}{\pgf@Ya}%
+\pgfmathsetmacro{\myza}{\pgf@Za}%
+\pgfmathsetmacro{\myxb}{\pgf@Xb}%
+\pgfmathsetmacro{\myyb}{\pgf@Yb}%
+\pgfmathsetmacro{\myzb}{\pgf@Zb}%
+\pgfmathparse@td@FPU{\myxa*\myxb+\myya*\myyb+\myza*\myzb}%
+%\typeout{P1=(\myxb,\myyb,\myzb),P2=(\myxa,\myya,\myza),P1.P2=(\pgmfmathresult)}%
+\fi%
+%\message{result = (\pgftemp@x,\pgftemp@y,\pgftemp@z)=\pgfmathresult^^J}%
+\xdef\tikz@td@type{0}% reset type to linear combination
+\pgfmathsmuggle\pgfmathresult\endgroup}%
+%
+\def\tikz@td@cc@add+{%
+\def\tikz@td@cc@factor{1}%
+\tikz@td@cc@factororcoordinate%
+}%
+\def\tikz@td@cc@sub-{%
+\def\tikz@td@cc@factor{-1}%
+\tikz@td@cc@factororcoordinate%
+}%
+\def\tikz@td@cc@vecprod x{%
+%\message{Ah, a vector product^^J}%
+\xdef\tikz@td@type{1}%
+\pgf@Xb=\pgf@Xa% store current vector in b
+\pgf@Yb=\pgf@Ya%
+\pgf@Zb=\pgf@Za%
+\pgf@Xa=0pt% reset a
+\pgf@Ya=0pt%
+\pgf@Za=0pt%
+\def\tikz@td@cc@factor{1}%
+\tikz@td@cc@factororcoordinate%
+}%
+\def\tikz@td@cc@scalprod o{%
+%\message{Ah, a scalar product^^J}%
+\xdef\tikz@td@type{2}%
+\pgf@Xb=\pgf@Xa% store current vector in b
+\pgf@Yb=\pgf@Ya%
+\pgf@Zb=\pgf@Za%
+\pgf@Xa=0pt% reset a
+\pgf@Ya=0pt%
+\pgf@Za=0pt%
+\def\tikz@td@cc@factor{1}%
+\tikz@td@cc@factororcoordinate%
+}%
+%
+% Check for a factor: If we see a (, its a coordinate...
+%
+\def\tikz@td@cc@factororcoordinate{%
+\pgfutil@ifnextchar({%)
+% Ok, found coordinate
+\tikz@td@cc@coordinate%
+}{%
+\tikz@td@cc@parse@factor%
+}%
+}%
+%
+% ... otherwise it's a factor. It ends at ...*(
+%
+\def\tikz@td@cc@parse@factor#1*({%
+\pgfmathparse@td@FPU{#1*\tikz@td@cc@factor}%
+\let\tikz@td@cc@factor=\pgfmathresult%
+\tikz@td@cc@coordinate(%)
+}%
+\def\tikz@td@cc@coordinate(#1){%
+\ParseCoord(#1)%
+\advance\pgf@Xa by\tikz@td@cc@factor\pgf@X
+\advance\pgf@Ya by\tikz@td@cc@factor\pgf@Y
+\advance\pgf@Za by\tikz@td@cc@factor\pgf@Z
+\tikz@td@cc@parse%
+}%
+\tikzset{declare function={torusx(\u,\v,\R,\r)=cos(\u)*(\R + \r*cos(\v));
+torusy(\u,\v,\R,\r)=(\R + \r*cos(\v))*sin(\u);
+torusz(\u,\v,\R,\r)=\r*sin(\v);
+vcrit1(\u,\th)=atan(tan(\th)*sin(\u));% first critical v value
+vcrit2(\u,\th)=180+atan(tan(\th)*sin(\u));% second critical v value
+vtest(\u,\v,\az,\el)=sin(-vcrit1(\u-\az,\el)+\v);
+disc(\th,\R,\r)=((pow(\r,2)-pow(\R,2))*pow(cot(\th),2)+%
+pow(\r,2)*(2+pow(tan(\th),2)))/pow(\R,2);% discriminant
+umax(\th,\R,\r)=ifthenelse(disc(\th,\R,\r)>0,asin(sqrt(abs(disc(\th,\R,\r)))),0);
+}}%
+%
+\tikzset{3d parse/.style={/utils/exec=\pgfmathtdparse{#1},%
+insert path={(\pgfmathresult)}},3d coordinate/.style args={#1=#2}{%
+/utils/exec=\pgfmathtdparse{#2},%
+insert path={(\pgfmathresult) coordinate #1}}}%
+\def\pgfmathprintvector#1{%
+\pgfutil@tempcnta=0%
+\pgfutil@for\pgf@tmp:={#1}\do{\advance\pgfutil@tempcnta by1}%
+\pgfutil@tempcntb=1%
+\pgfutil@for\pgf@tmp:={#1}\do{\advance\pgfutil@tempcntb by1%
+\ifnum\the\pgfutil@tempcntb<\the\pgfutil@tempcnta
+\pgfmathprintnumber\pgf@tmp,%
+\else
+\pgfmathprintnumber\pgf@tmp
+\fi}%
+}%
+%%
+%% predefined pics
+% based on https://en.wikipedia.org/wiki/Circumscribed_circle
+\tikzset{pics/3d circle through 3 points/.style={code={%
+ \tikzset{3d/circle through 3 points/.cd,#1}%
+ \edef\temp{\noexpand\path[overlay,
+ 3d coordinate={(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}b)=\pgfkeysvalueof{/tikz/3d/circle through 3 points/A}-\pgfkeysvalueof{/tikz/3d/circle through 3 points/C}},
+ 3d coordinate={(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}a)=\pgfkeysvalueof{/tikz/3d/circle through 3 points/B}-\pgfkeysvalueof{/tikz/3d/circle through 3 points/C}},
+ 3d coordinate={(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}c)=\pgfkeysvalueof{/tikz/3d/circle through 3 points/A}-\pgfkeysvalueof{/tikz/3d/circle through 3 points/B}},
+ 3d coordinate={(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}n)=(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}a)x(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}b)}];}%
+ \temp
+ \pgfmathsetmacro{\lengthn}{sqrt(TD("(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}n)o(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}n)"))}
+ \ifdim\lengthn pt<0.02pt
+ \message{The points are (almost) on a line. Circle cannot be determined.}
+ \else
+ \pgfmathsetmacro{\tmpradius}{sqrt(TD("(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}a)o(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}a)"))*%
+ sqrt(TD("(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}b)o(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}b)"))*sqrt(TD("(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}c)o(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}c)"))/%
+ (2*\lengthn)}
+ \pgfmathsetmacro{\coeffa}{-1*TD("(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}b)o(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}b)")/(2*TD("(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}n)o(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}n)"))}
+ \pgfmathsetmacro{\coeffb}{TD("(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}a)o(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}a)")/(2*TD("(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}n)o(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}n)"))}
+ \edef\temp{%
+ \noexpand\path[overlay,3d coordinate={(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}u)=\coeffa*(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}a)x(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}n)},
+ 3d coordinate={(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}v)=\coeffb*(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}b)x(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}n)}];
+ \noexpand\path[3d coordinate={(\pgfkeysvalueof{/tikz/3d/circle through 3 points/center name})=\pgfkeysvalueof{/tikz/3d/circle through 3 points/C}+(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}u)+(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}v)}];
+ }%
+ \temp
+ \pgfmathsetmacro{\normalizationa}{1/sqrt(TD("(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}a)o(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}a)"))}
+ \pgfmathsetmacro{\normalizationn}{1/sqrt(TD("(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}n)o(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}n)"))}
+ \edef\temp{%
+ \noexpand\path[overlay,3d coordinate={(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}a)=\normalizationa*(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}a)},
+ 3d coordinate={(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}n)=\normalizationn*(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}n)},
+ 3d coordinate={(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}c)=(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}a)x(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}n)}];
+ }%
+ \temp
+ \edef\temp{%
+ \noexpand\begin{scope}[plane x={(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}a)},plane y={(\pgfkeysvalueof{/tikz/3d/circle through 3 points/auxiliary coordinate prefix}c)},canvas is plane]
+ \noexpand\draw[pic actions] (\pgfkeysvalueof{/tikz/3d/circle through 3 points/center name}) circle[radius=\tmpradius];
+ \noexpand\end{scope}}%
+ \temp
+ \fi
+}},3d/circle through 3 points/.cd,A/.initial={(1,0,0)},B/.initial={(0,1,0)},
+C/.initial={(0,0,1)},
+auxiliary coordinate prefix/.initial=tmp,center name/.initial=M}%
+%%
+%% decorations
+%%
+\newif\ifcoil@closed%
+\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,%
+3d coil closed/.code=\coil@closedtrue%
+}%
+% 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-\generaloffset pt%%
+}%
+% coil decoration%
+%%
+% Parameters: \pgfdecorationsegmentamplitude, \pgfdecorationsegmentlength,%
+\pgfdeclaredecoration{3d complete coil}{initial}%
+{ %
+ \state{initial}[width=0.5*\pgfdecorationsegmentlength,%
+ next state=coil, persistent precomputation={% from https://tex.stackexchange.com/a/25689/121799%
+ \pgfmathsetmacro\matchinglength{\pgfdecoratedinputsegmentlength / int(\pgfdecoratedinputsegmentlength/\pgfdecorationsegmentlength)}%
+ \setlength{\pgfdecorationsegmentlength}{\matchinglength pt}%
+ \tikzset{get stroke color}%
+ \pgfmathsetmacro{\generaloffset}{\pgfdecorationsegmentlength}%
+ \pgfmathsetmacro{\initialoffset}{1.5*\pgfdecorationsegmentlength}%
+ \pgfmathsetmacro{\auxoffset}{2.5*\pgfdecorationsegmentlength}%
+ }] { %
+ % line in the back%
+ %%
+ \pgfsetstrokecolor{\TDCoilColor}%
+ \pgfsetfillcolor{\TDCoilColor}%
+ \pgfsetstrokeopacity{\TDCoilOpacity}%
+ \pgfsetlinewidth{\TDCoilWidth} %
+ \ifcoil@closed%
+ \begingroup%
+ \def\generaloffset{\auxoffset}%
+ \pgfpathmoveto{\pgfpoint@onthreedcoil{1 }{ 1 }{15}}%
+ \pgfpathcurveto%
+ {\pgfpoint@onthreedcoil{1.555}{ 1 }{16}}%
+ {\pgfpoint@onthreedcoil{2 }{ 0.555}{17}}%
+ {\pgfpoint@onthreedcoil{2 }{ 0 }{18}}%
+ \pgfcoordinate{TD@coilast}{\pgfpoint@onthreedcoil{2 }{ 0 }{18}}%
+ \pgfcoordinate{TD@coilfirst}{\pgfpoint@onthreedcoil{1 }{ 1 }{15}}%
+ \pgfusepath{stroke} %
+ \pgfsetstrokecolor{\TDCoilColor}%
+ \endgroup%
+ \fi%
+ \begingroup %%
+ \def\generaloffset{\initialoffset}%
+ \ifcoil@closed%
+ \pgfpathmoveto{\pgfpointanchor{TD@coilast}{center}}%
+ \else%
+ \pgfpathmoveto{\pgfpointorigin}%
+ \fi%
+ \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 }{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} %
+ \pgfpathmoveto{\pgfpoint@onthreedcoil{1 }{ 1 }{15}}%
+ \pgfpathcurveto%
+ {\pgfpoint@onthreedcoil{1.555}{ 1 }{16}}%
+ {\pgfpoint@onthreedcoil{2 }{ 0.555}{17}}%
+ {\pgfpoint@onthreedcoil{2 }{ 0 }{18}}%
+ \pgfcoordinate{TD@coilast}{\pgfpoint@onthreedcoil{2 }{ 0 }{18}} %
+ \pgfusepath{stroke} %
+ \endgroup%
+ }%
+ \state{coil}[switch if less than=%%
+ 1.9*\pgfdecorationsegmentlength to last,%
+ width=+\pgfdecorationsegmentlength]%
+ { % line in the back%
+ %%
+ \pgfsetstrokecolor{\TDCoilColor}%
+ \pgfsetfillcolor{\TDCoilColor}%
+ \pgfsetstrokeopacity{\TDCoilOpacity}%
+ \pgfpathmoveto{\pgfpointanchor{TD@coilast}{center}}%
+ \pgfsetlinewidth{\TDCoilWidth} %
+ \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} %
+ \pgfpathmoveto{\pgfpoint@onthreedcoil{1 }{ 1 }{15}}%
+ \pgfpathcurveto%
+ {\pgfpoint@onthreedcoil{1.555}{ 1 }{16}}%
+ {\pgfpoint@onthreedcoil{2 }{ 0.555}{17}}%
+ {\pgfpoint@onthreedcoil{2 }{ 0 }{18}}%
+ \pgfusepath{stroke} %
+ \pgfcoordinate{TD@coilast}{\pgfpoint@onthreedcoil{2 }{ 0 }{18}} %
+ }%
+ \state{last}[next state=final]%
+ { % line in the back%
+ %%
+ \pgfsetstrokecolor{\TDCoilColor}%
+ \pgfsetfillcolor{\TDCoilColor}%
+ \pgfsetstrokeopacity{\TDCoilOpacity}%
+ \pgfpathmoveto{\pgfpointanchor{TD@coilast}{center}}%
+ \pgfsetlinewidth{\TDCoilWidth} %
+ \pgfpathcurveto%
+ {\pgfpoint@onthreedcoil{2 }{-0.555}{7}}%
+ {\pgfpoint@onthreedcoil{1.555}{-1 }{8}}%
+ {\pgfpoint@onthreedcoil{1 }{-1 }{9}}%
+ \pgfusepath{stroke} %
+ % %
+ % draw the thick foreground path%
+ %%
+ \ifcoil@closed %\pgfpointanchor{TD@coilfirst}{center}%
+ %%
+ % 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}}%
+ {\pgfpointanchor{TD@coilfirst}{center}}%
+ % 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} %
+ \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}}%
+ {\pgfpointanchor{TD@coilfirst}{center}}%
+ % draw the curve back shifted %
+ \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} %
+ \else%
+ %%
+ % 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} %
+ \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 shifted %
+ \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} %
+ \fi%
+ \pgfpathmoveto{\pgfpoint@onthreedcoil{1 }{ 1 }{15}}%
+ \ifcoil@closed %TD@coilfirst%
+ \else%
+ \pgfpathcurveto%
+ {\pgfpoint@onthreedcoil{1.555}{ 1 }{16}}%
+ {\pgfpoint@onthreedcoil{2 }{ 0.555}{17}}%
+ {\pgfpoint@onthreedcoil{2 }{ 0 }{18}}%
+ \fi%
+ \pgfusepath{stroke} %
+ %\pgfcoordinate{TD@coilast}{\pgfpoint@onthreedcoil{2 }{ 0 }{18}} %
+ }%
+ \state{final}%
+ {%
+ \pgfpathmoveto{\pgfpointdecoratedpathlast}%
+ \tikzset{restore stroke color/.expand once=\pgfsavedstrokecolor}%
+ }%
+}%
+\makeatother
+\endinput