How to draw Micrometer scale using TikZ

This is an attempt of a 3d answer. I acknowledge and appreciate comments by KJO that made me realize that this is not really realistic and by Raaja that made me choose a perhaps more intuitive offset. ;-)

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot} 
\usetikzlibrary{3d,calc}

\begin{document}

\tdplotsetmaincoords{00}{00}
\foreach \Z in {1.5,3,...,30,28.5,27,...,3}
{\tdplotsetrotatedcoords{0}{\Z}{00}
\pgfmathsetmacro{\VernierLength}{\Z/2} % <- this is the length in mm you want to show
\begin{tikzpicture}[tdplot_rotated_coords,font=\sffamily]
%  \begin{scope}[xshift=-5cm]
%    \draw[-latex] (0,0,0) -- (1,0,0) node[pos=1.1]{$x$};
%    \draw[-latex] (0,0,0) -- (0,1,0) node[pos=1.1]{$y$};
%    \draw[-latex] (0,0,0) -- (0,0,1) node[pos=1.1]{$z$};
%  \end{scope}
 \path[tdplot_screen_coords,use as bounding box] (-3,-3) rectangle (5,3);
 \path[tdplot_screen_coords] (5,3) node[anchor=north east] 
    {$\mathsf{L}=\VernierLength$};
 \begin{scope}
   \begin{scope}[canvas is yz plane at x=0]
    \path (0,0) coordinate (M1);
    \draw (180:1) arc(180:0:1);
   \end{scope}
   \begin{scope}[canvas is yz plane at x=1.5]
    \path (0,0) coordinate (M2);
    \draw let \p1=($(M2)-(M1)$),\n1={0*atan2(\y1,\x1)+atan2(1,1.5)/2.5} in
     ($(M1)+(-\n1/2:1)$) coordinate (TL) -- ($(M2)+(-\n1/2:2)$) coordinate (TR)
     ($(M1)+(180+\n1/2:1)$) coordinate (BL) -- ($(M2)+(180+\n1/2:2)$) coordinate (BR)
     (BR) arc(180+\n1/2:-\n1/2:2);
   \end{scope}
   \begin{scope}
    \draw plot[variable=\t,domain=0:360,smooth] 
      (-\VernierLength/10-0.5,{cos(\t)},{sin(\t)});
    \draw[clip] plot[variable=\t,domain=0:180,smooth] 
      (-\VernierLength/10-0.5,{cos(\t)},{sin(\t)})
      -- plot[variable=\t,domain=180:0,smooth] 
      (0,{cos(\t)},{sin(\t)}) -- cycle;
    \draw[thick] (-\VernierLength/10,0,1) -- (0,0,1) 
      plot[variable=\t,domain=60:110,smooth] 
      (-\VernierLength/10,{cos(\t)},{sin(\t)});
    \path let 
      \p1=($(-\VernierLength/10,{cos(120)},{sin(120)})-(-\VernierLength/10,{cos(110)},{sin(110)})$),
       \n1={90+atan2(\y1,\x1)} in (-\VernierLength/10,{cos(120)},{sin(120)})
        node[rotate=\n1,yscale={cos(30)},transform shape]{0};         
    \pgfmathtruncatemacro{\Xmax}{\VernierLength/2}
    \ifnum\Xmax>0
    \foreach \X in {1,...,\Xmax}
    {\ifodd\X
      \draw plot[variable=\t,domain=90:110,smooth] 
      (-\VernierLength/10+\X/5,{cos(\t)},{sin(\t)});
%     \path let 
%       \p1=($(-\VernierLength/10+\X/5,{cos(120)},{sin(120)})-(-\VernierLength/10+\X/5,{cos(110)},{sin(110)})$),
%        \n1={90+atan2(\y1,\x1)} in (-\VernierLength/10+\X/5,{cos(120)},{sin(120)})
%         node[rotate=\n1,yscale={cos(30)},transform shape]{\X};
     \else
      \draw plot[variable=\t,domain=90:70,smooth] 
      (-\VernierLength/10+\X/5,{cos(\t)},{sin(\t)});
%     \path let 
%       \p1=($(-\VernierLength/10+\X/5,{cos(60)},{sin(60)})-(-\VernierLength/10+\X/5,{cos(70)},{sin(70)})$),
%        \n1={-90+atan2(\y1,\x1)} in (-\VernierLength/10+\X/5,{cos(60)},{sin(60)})
%         node[rotate=\n1,yscale={cos(30)},transform shape]{\X};
     \fi
     }
    \fi
   \end{scope} 
   %
   \begin{scope}[canvas is yz plane at x=3.5]
    \path (0,0) coordinate (M3);
    \draw (180:2) arc(180:0:2);
    \draw ($(M2)+(0:2)$) -- ($(M3)+(0:2)$)
    ($(M2)+(180:2)$) -- ($(M3)+(180:2)$);
   \end{scope}
     \pgfmathtruncatemacro{\Offset}{180+10*\VernierLength*7.2-12.5*7.2}
     \pgfmathtruncatemacro{\Xmin}{10*\VernierLength+1-12.5}
     \pgfmathtruncatemacro{\Xmax}{\Xmin+23}
    \foreach \X [evaluate=\X as \Y using {int(mod(\X,5))},
      evaluate=\X as \LX using {int(mod(\X,50))}] in {\Xmin,...,\Xmax}
    {\ifnum\Y=0
       \draw[thin] let 
       \p1=($(0.6,{(1+0.4)*cos(\Offset-\X*7.2)},{(1+0.4)*sin(\Offset-\X*7.2)})-
       (0,{cos(\Offset-\X*7.2)},{sin(\Offset-\X*7.2)})$),
       \p2=($(0.6,{(1+0.4)*cos(\Offset-\X*7.2)},{(1+0.4)*sin(\Offset-\X*7.2)})-
       (0.6,{(1+0.4)*cos(\Offset-\X*7.2+1)},{(1+0.4)*sin(\Offset-\X*7.2+1)})$),
       \p3=($(0.6,{0},{(1+0.4)})-
       (0.6,{(1+0.4)*cos(91)},{(1+0.4)*sin(91)})$),
       \n1={atan2(\y1,\x1)},\n2={veclen(\x2,\y2)/veclen(\x3,\y3)} in
       (0,{cos(\Offset-\X*7.2)},{sin(\Offset-\X*7.2)})
        -- (0.6,{(1+0.4)*cos(\Offset-\X*7.2)},{(1+0.4)*sin(\Offset-\X*7.2)})
        node[pos=1.5,rotate=\n1,yscale={\n2},transform shape]{\LX};
     \else
       \draw[thin] (0,{cos(\Offset-\X*7.2)},{sin(\Offset-\X*7.2)})
        -- (0.3,{(1+0.2)*cos(\Offset-\X*7.2)},{(1+0.2)*sin(\Offset-\X*7.2)});
     \fi}
 \end{scope}
\end{tikzpicture}}
\end{document} 

enter image description here

And here is a trick to draw the ticks. Call the point where the diagonal points intersect P. Then the ticks point to this point. Of course, in the end you want to remove the excess lines by clipping.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[font=\sffamily]
 \draw (0,0)--(-2,0) (0,-2)--(-2,-2);
 \draw[thin] (0,0)--(0,-2);
 \draw (0,0)coordinate (TL) --(1.5,1) coordinate (TR)  --(3.5,1) ;
 \draw (0,-2) coordinate (BL)--(1.5,-3)  coordinate (BR) --(3.5,-3) ;
 \draw[thin] (1.5,1)--(1.5,-3);
 \draw (-2,-2) to[out=130,in=-130] (-2,-1) to[out=130,in=-130] (-2,0);
 \draw[very thin] (-2,-1) to[out=50,in=-50] (-2,0);
 \draw (3.5,1) to[out=-50,in=50] (3.5,-1) to[out=-50,in=50] (3.5,-3);
 \draw[very thin] (3.5,-1) to[out=-130,in=130] (3.5,-3);
 \path (intersection cs:first line={(TL)--(TR)}, second line={(BL)--(BR)})
  coordinate (P);
 \clip (TL) -- (TR) -- (BR) -- (BL) -- cycle;
 \foreach \X [evaluate=\X as \Y using {int(mod(\X,5))}] in {1,...,17}
 {\ifnum\Y=0
   \draw[shorten >=-20pt] (P) -- (0,-2+\X/9) node[pos=1.65]{\X};
 \else
   \draw[shorten >=-7pt] (P) -- (0,-2+\X/9);
 \fi  }
\end{tikzpicture}
\end{document}

enter image description here


Adaptions:

  • I set the orign to the "0" of the horizontal scale.

Description:

  • added 3 parameters:
    • \lenx is the horizontal length
    • \xscale is the scaling of one horizontal length unit
    • \startrange is the starting number of the vertical scale
  • for loops and modulo calculations are used for drawing the scales

Code:

\documentclass[margin=3mm,tikz]{standalone}

\begin{document}

\newcommand{\lenx}{5.3} % e.g.: 0.4 or 5.3
\newcommand{\xscale}{.2}
\newcommand{\startrange}{0} % e.g.: 0 or 7

\begin{tikzpicture}
    % scale right
    \foreach \i in {1, ..., 18} {
        \pgfmathparse{Mod(\i-1+\startrange,5)==0?1:0}
        \ifnum\pgfmathresult>0
            % long line with number
            \draw[blue] (\lenx*\xscale, -1+\i*2/19) -- (\lenx*\xscale+.5, -1+\i*2.5/19 -.25) node[right]{\pgfmathparse{int(\i-1+\startrange)}\pgfmathresult};%
        \else
            % short line
            \draw[blue] (\lenx*\xscale, -1+\i*2/19) -- (\lenx*\xscale+.25, -1+\i*2.25/19 -.125);
        \fi
    }

    % horizontal scale (left)
    \draw[red] (0,0) -- (\lenx*\xscale,0);
    \draw[thick] (0,.3) -- (0,-.15) node[below]{0};
    \pgfmathparse{int(\lenx)}
    \foreach \i in {0, ..., \pgfmathresult} {
        \pgfmathparse{Mod(\i,2)==0?1:0}
        \ifnum\pgfmathresult>0
            \draw[] (\i*\xscale,0) -- (\i*\xscale,.15);
        \else
            \draw[] (\i*\xscale,0) -- (\i*\xscale,-.15);
        \fi
    }

    % borders
    \draw[thin, green] (\lenx*\xscale,1)--(\lenx*\xscale,-1);
    \draw (-.5,1)--(\lenx*\xscale,1);
    \draw (-.5,-1)--(\lenx*\xscale,-1);

    \draw (\lenx*\xscale,1)--++(1.5,1)--++(2,0);
    \draw (\lenx*\xscale,-1)--++(1.5,-1)--++(2,0);
    \draw[thin] (\lenx*\xscale+1.5,2)--++(0,-4);

    % curvy lines (left and right)
    \draw (-.5,-1) to[out=130,in=-130] (-.5,0) to[out=130,in=-130] (-.5,1);
    \draw[very thin] (-.5,0) to[out=50,in=-50] (-.5,1);
    \draw (\lenx*\xscale+3.5,2) to[out=-50,in=50] (\lenx*\xscale+3.5,0) to[out=-50,in=50] (\lenx*\xscale+3.5,-2);
    \draw[very thin] (\lenx*\xscale+3.5,0) to[out=-130,in=130] (\lenx*\xscale+3.5,-2);
\end{tikzpicture}
\end{document}

Results:

enter image description here


A PSTricks solution just for fun purposes. I focus on the scale. The aesthetic aspects are too trivial.

\documentclass[pstricks,border=12pt,12pt]{standalone}
\usepackage{multido}
\usepackage[nomessages]{fp}

\makeatletter
\def\vernier#1{%
    \begingroup
    \psset{yunit=2mm,xunit=1mm,linecolor=red,linewidth=.8pt,linecap=0}
    \pspolygon[fillcolor=yellow,fillstyle=solid,opacity=.9,linestyle=none,linewidth=.8pt,linearc=1pt](0,-6)(0,6)(6,7.5)(10,7.5)(10,-7.5)(6,-7.5)
    \multido{\iy=-5+1,\in={\numexpr#1-5\relax}+1}{11}{%
        \pst@mod\in{50}\lbl
        \pst@mod\lbl{5}\tmp
        \psline(0,\iy)(!\tmp\space 0 ne {2} {5} ifelse \iy\space)
        \ifnum\tmp=0\uput[0](3.5,\iy){\textcolor{red}{$\lbl$}}\fi
    }
    \psline(.5\pslinewidth,-5)(.5\pslinewidth,5)
    \endgroup
}

\newcommand\micrometer[1]{%
\bgroup
\psset{xunit=.2mm,yunit=1cm,linewidth=1.6pt}
\begin{pspicture}[linecolor=black,linecap=2](0,-1.3)(150,1.7)
    \FPeval\args{trunc(#1*100:0)}
    \pst@mod{\args}{100}\position
    \FPeval\lbl{trunc(args/100:0)}
    \multido{\ix=0+50}{4}{%
        \pst@mod\ix{100}\rem
        \ifnum\rem=0
                \psline(\ix,-17pt)(\ix,17pt)
                \uput[90](\ix,16pt){\lbl}
                \FPeval\lbl{trunc(lbl+1:0)}
        \else
                \pst@mod\ix{50}\rem
                \ifnum\rem=0
                    \psline(\ix,-5pt)(\ix,5pt)
                \fi
        \fi}
    \psline(150,0)
    \rput(\dimexpr\position\psxunit-.4pt\relax,0){\vernier{\args}}
    \rput(75,1.75){\scriptsize#1}
\end{pspicture}
\egroup
}
\makeatother

\begin{document}
\multido{\n=3.00+0.01}{100}{\micrometer{\n}}
%\micrometer{2.34}
\end{document}

enter image description here

Tags:

Tikz Pgf