[Tex/LaTex] Drawing screw threads in 3D using TikZ

tikz-pgf

I wonder if it would be possible to draw screw threads in 3D using TikZ. This question (how to draw a real corkscrew) is similar, but the only answer given is an asymptote solution. I am looking for a TikZ solution.

This question (How to define a screw as a decoration in TikZ) uses the decorations library to create a 2D drawing of a screw thread. But I'm looking to draw a screw thread in 3D. Here is a minimal example:

enter image description here

Here I have drawn a cylinder using code from this answer, and drawn the 2D screw using code from this answer.

Some ideas

I think there is a lot of potential for such a piece of code. For example, one could envisage being able to draw lots of different types of screws based on parameters like these: (Source: thorlabs.com)

enter image description here

This would allow you to draw a multitude of different screws for which you could also specify different screw head shapes and screw drive types: (Source: boltdepot.com)

enter image description here

But this is certainly an ambitious goal. For the time being, is it possible to just draw a simple screw thread in 3D (the head shape can just be a plain cylinder). Additionally, would it be possible to draw a corresponding internal screw thread like this:

enter image description here

Code

\documentclass[tikz,margin=0.5cm]{standalone}
\usetikzlibrary{shapes.geometric,decorations}

% New decoration for screws
\tikzset{/pgf/decoration/.cd,
    head width/.initial=6pt,
    head length/.initial=1.5pt,
    thread separation/.initial=1.0pt,
    thread amplitude/.initial=0.5pt,
    screw radius/.initial=1.2pt,
}
% definition of the decoration
\pgfdeclaredecoration{screw}{initial}
{
  \state{initial}[width=\pgfkeysvalueof{/pgf/decoration/head length},%
                  next state=midd]
  {
    \def\headlength{%
      \pgfkeysvalueof{/pgf/decoration/head length}%
    }
    \def\headwidth{%
      \pgfkeysvalueof{/pgf/decoration/head width}%
    }
    \def\screwradius{%
      \pgfkeysvalueof{/pgf/decoration/screw radius}%
    }
    % First line
    \pgfpathlineto{\pgfpoint{0.0pt}{\headwidth/2}}
    \pgfpathlineto{\pgfpoint{\headlength}{\screwradius}}
    % Second line
    \pgfpathmoveto{\pgfpoint{0.0pt}{0.0pt}}
    \pgfpathlineto{\pgfpoint{0.0pt}{-\headwidth/2}}
    \pgfpathlineto{\pgfpoint{\headlength}{-\screwradius}}
  }
  \state{midd}[width=\pgfkeysvalueof{/pgf/decoration/thread separation}*2]
  {
    \def\threadseparation{%
      \pgfkeysvalueof{/pgf/decoration/thread separation}%
    }
    \def\threadamplitude{%
      \pgfkeysvalueof{/pgf/decoration/thread amplitude}%
    }
    \def\screwradius{%
      \pgfkeysvalueof{/pgf/decoration/screw radius}%
    }
    % First line
    \pgfpathmoveto{\pgfpoint{0pt}{\screwradius}}
    \pgfpathlineto{\pgfpoint{0.5*\threadseparation}{\screwradius+\threadamplitude}}
    \pgfpathlineto{\pgfpoint{1.0*\threadseparation}{\screwradius}}
    \pgfpathlineto{\pgfpoint{1.5*\threadseparation}{\screwradius-\threadamplitude}}
    \pgfpathlineto{\pgfpoint{2.0*\threadseparation}{\screwradius}}
    % Second line
    \pgfpathmoveto{\pgfpoint{0pt}{-\screwradius}}
    \pgfpathlineto{\pgfpoint{0.5*\threadseparation}{-\screwradius-\threadamplitude}}
    \pgfpathlineto{\pgfpoint{1.0*\threadseparation}{-\screwradius}}
    \pgfpathlineto{\pgfpoint{1.5*\threadseparation}{-\screwradius+\threadamplitude}}
    \pgfpathlineto{\pgfpoint{2.0*\threadseparation}{-\screwradius}}
    % Thread
    \pgfpathmoveto{\pgfpoint{0.5*\threadseparation}{\screwradius+\threadamplitude}}
    \pgfpathlineto{\pgfpoint{1.5*\threadseparation}{-\screwradius+\threadamplitude}}
  }
  \state{final}
  {
    \def\screwradius{%
      \pgfkeysvalueof{/pgf/decoration/screw radius}%
    }
    %\pgfpathlineto{\pgfpointdecoratedpathlast}
    \pgfpathmoveto{\pgfpoint{0pt}{\screwradius}}
    \pgfpathlineto{\pgfpoint{2.0pt}{0pt}}
    \pgfpathlineto{\pgfpoint{0pt}{-\screwradius}}
  }
}

\begin{document}
\begin{tikzpicture}

\node at (0,0) [cylinder, shape border rotate=90, draw, minimum height=25mm, minimum width=5mm,anchor=south] {};

\begin{scope}[xshift=1cm]
 \node (A) at (0,25mm) {};
  \node (B) at (0,0) {};
  \draw[decorate, decoration={screw, screw radius=5pt, head width=15pt, head length=3pt}] (A) -- (B);
\end{scope}

\end{tikzpicture}
\end{document}

Best Answer

Just for fun, an option with 2D drawings, using decorations; it seems to me that there is no pure 3D engine in tikz for the parametric drawing for solids, with operations such as: extrusions, cuts, bevelling, etc; I do not think it's the right framework for these drawings,but its not imposible like @marmot's answer shows; there are other free software such as blender, or free CAD, or with student and payment licenses like Autodesk Inventor. with which you can generate pdf documents and work them in tikz or with inkscape ...


Tikz 2D RESULT:

enter image description here

MWE:

% arara: pdflatex: {synctex: yes, action: nonstopmode}
% By J. Leon V. Share as Beerware philosophy
\documentclass[border=20pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.markings,shadings,decorations.shapes}


\begin{document}
    \begin{tikzpicture}[
        %Environment Styles
        screw1/.style={
            left color=black!50, right color=black!50, middle color=black!25,
            postaction={
                decorate,
                decoration={
                    markings,
                    mark=at position 0 
                    with {
                        \path [draw,left color=black!80, right color=black!25, middle color=white] 
                        (0,-0.5) -- ++(0.5,0.25) -- ++(0.5,0) arc (-90:90:1/6 and 0.25) -- ++(-0.5,0)-- (0,0.5) arc (90:-90:1/3 and 0.5);
                        \draw[fill=white] ellipse [x radius=1/3, y radius=0.5];
                        \foreach \r in {45,-45,135,-135}{
                            \foreach \i [evaluate={\s=30;}] in {0,2,...,30}{
                                \fill [black, fill opacity=1/50] 
                                (0,0) -- (\r+\s-\i:1/3 and 0.5) 
                                arc (\r+\s-\i:\r-\s+\i:1/3 and 0.5)  -- cycle;
                                }
                        }
                        \begin{scope}[scale=2,cm={-1/3,0.5,1/3,0.5,(0,0)}]
                        \draw (45:2pt) 
                            |- (90:0.25) -| (135:2pt) -| (180:0.25) |- (-135:2pt) 
                            |-(-90:0.25) -| (-45:2pt) -| (0:0.25) |-cycle;
                        \end{scope}
                    }
                }
            },
            postaction={
                decorate,
                decoration={
                    markings,
                    mark=between positions 0.5cm and 1 step 0.3cm
                    with {
                        \path [left color=black!40, right color=black!25, middle color=white] 
                        (0,-0.25) arc (-90:90:1/6 and 0.25) -- ++(0.3,0) arc (90:-90:1/6 and 0.25) -- cycle;
                        \draw(0,-.25) --++(0.12,0) coordinate (A);
                        \draw(0.08,.25) --++(0.2097,0);
                        \draw[left color=black!40, right color=black!25, middle color=white](0,.25) [out=45,in=-135]
                            to ++(0.05,0.05)[out=0,in=55] to (0.2,-0.3)[out=180,in=0] to (A)[out=55,in=0]
                            to cycle;
                    }
                }
            },
            postaction={
                decorate,
                decoration={
                    markings,
                    mark=at position 1
                    with {
                        \path [draw,left color=black!40, right color=black!25, middle color=white] 
                        (0.1,0.25) -- ++(0.3,0) -- ++(0.8,-0.25) -- ++(-0.8,-0.25) --++(-0.3,0) ;
                        \draw[left color=black!40, right color=black!25, middle color=white](0.1,.25) [out=45,in=-135]
                            to ++(0.05,0.05)[out=0,in=55] to (0.25,-0.3)[out=180,in=0] to ++(-0.05,0.05)[out=55,in=0]
                            to cycle;
                        \draw[left color=black!40, right color=black!25, middle color=white](0.45,.23) [out=45,in=-135]
                            to ++(0.05,0.02)[out=0,in=55] to (0.65,-0.23)[out=180,in=0] to ++(-0.05,0.05)[out=55,in=0]
                            to cycle;
                        \draw[left color=black!40, right color=black!25, middle color=white](0.8,.12) [out=45,in=-135]
                            to ++(0.05,0.02)[out=0,in=55] to (0.95,-0.13)[out=180,in=0] to ++(-0.05,0.05)[out=55,in=0]
                            to cycle;
                    }
                }
            }
        },
        scrthr/.style={
            postaction={
                decorate,
                decoration={
                    markings,
                    mark=at position 0
                    with {
                        \path [draw,left color=black!80, right color=black!25, middle color=white] 
                        (0,-0.25) arc (-90:-270:1/6 and 0.25) -- ++(0.1,0) arc (-270:-90:1/6 and 0.25);
                        \path [draw,left color=black!80, right color=black!25, middle color=white] 
                        (0.1,-0.25) arc (-90:-270:1/6 and 0.25) -- ++(0.1,0) arc (-270:-90:1/6 and 0.25);
                        \path [draw,left color=black!80, right color=black!25, middle color=white] 
                        (0.2,-0.25) arc (-90:-270:1/6 and 0.25) -- ++(0.1,0) arc (-270:-90:1/6 and 0.25);
                        \path [left color=black!80, right color=black!25, middle color=white] 
                        (0,-0.5) -- ++(0.5,0) arc (-90:90:1/3 and 0.5) -- ++(-0.5,0)-- (0,0.5) arc (90:-90:1/3 and 0.5);
                        \draw[fill=white,,even odd rule] ellipse [x radius=1/3, y radius=0.5]
                        ellipse [x radius=1/6, y radius=0.25];
                        \foreach \r in {45,-45,135,-135}{
                            \foreach \i [evaluate={\s=30;}] in {0,2,...,30}{
                                \fill [black, fill opacity=1/50] 
                                (0,0) -- (\r+\s-\i:1/3 and 0.5) 
                                arc (\r+\s-\i:\r-\s+\i:1/3 and 0.5)  -- cycle;
                                }
                        }
                    }
                }
            },
            postaction={
                decorate,
                decoration={
                    markings,
                    mark=between positions 0.2cm and 1 step 0.2cm
                    with {
                        \path [left color=black!80, right color=black!25, middle color=white] 
                        (0,-0.5) -- ++(0.5,0) arc (-90:90:1/3 and 0.5) -- ++(-0.5,0)-- (0,0.5) arc (90:-90:1/3 and 0.5);
                    }
                }
            }
        }
    ]


    \draw[screw1](0,0)--++(0,-1.5);
    \draw[screw1](2,0)--++(0,-3.5);
    \draw[screw1](4,0)--++(1,-2);
    \draw[scrthr](0,-3.5)--++(0,-2);
    \draw[scrthr](2,-5.5)--++(0,-4);
    \draw[scrthr](6,-4)--++(1,-2);

    \end{tikzpicture}
\end{document}

Using real 3D framework this case > Inventor:

enter image description here

Related Question