29

How to draw these two figures in TikZ?

enter image description here

I have gone as far as

\documentclass[margin=3mm,tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\draw (0,0)--(-2,0);
\draw (0,-2)--(-2,-2);
\draw[thin] (0,0)--(0,-2);
\draw (0,0)--(1.5,1)--(3.5,1);
\draw (0,-2)--(1.5,-3)--(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);
\end{tikzpicture}
\end{document}

enter image description here

but I got stuck when I tried to insert the numbers and the small lines. They should have accurate slopes, and,

enter image description here

the red line and the blue line should not meet the green line at the same point.

These criterias are too difficult and complicated for me to overpass.

Can you help me? Any help is very appreciated.

  • 3
    Welcome to TeX.SX! It's good that you provided a minimal working example (MWE), but your title could be more descriptive. – dexteritas Feb 1 at 13:59
  • 2
    Title is amended – user170109 Feb 1 at 15:22
  • 1
    @JerryCoffin I know, but it was more eye catching on the tongue than simply how to draw "this" and sleeve and thimble was too wieldy but I can change it if you think its best to aim for finer precision :-) – user170109 Feb 1 at 21:19
  • I agree with @JerryCoffin. An accurate title would be "micrometer". For an example of a Vernier micrometer, see: en.wikipedia.org/wiki/Vernier_scale – Dithermaster Feb 2 at 23:47
  • @Dithermaster OK Micrometer scale it is – user170109 Feb 3 at 2:08
31

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

27

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

15

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

  • 3
    +1. However, I think the OP only asks how to draw the figures :) – user156344 Feb 1 at 14:57
  • 3
    @JouleV: I was not trying to answer the OP question. :-) – Money Oriented Programmer Feb 1 at 14:58
  • 8
    ... as usual ;-). – AlexG Feb 1 at 18:32
  • @ArtificialStupidity Flags as NAA. – EKons Feb 3 at 11:35
  • 1
    @EKons: Flags as ANA. – Money Oriented Programmer Feb 3 at 12:33
3

Foreword: This answer is only a tiny improvement of @dexteritas' answer so that the output figure fits the given figure more accurately.1 Don't accept this answer.


I make a little change in the \startrange definition and the y-coordinate of points in the horizontal scale.

Diagram 1:

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

\begin{document}

\newcommand{\lenx}{5.3} % e.g.: 0.4 or 5.3
\newcommand{\xscale}{.2}
\newcommand{\startrange}{1} % 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 (\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 (\lenx*\xscale, -1+\i*2/19) -- (\lenx*\xscale+.25, -1+\i*2.25/19 -.125);
        \fi
    }

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

    % borders
    \draw[thin] (\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}

enter image description here

Diagram 2:

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

\begin{document}

\newcommand{\lenx}{0.4} % e.g.: 0.4 or 5.3
\newcommand{\xscale}{.2}
\newcommand{\startrange}{6} % 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 (\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 (\lenx*\xscale, -1+\i*2/19) -- (\lenx*\xscale+.25, -1+\i*2.25/19 -.125);
        \fi
    }

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

    % borders
    \draw[thin] (\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}

enter image description here


1 Micrometer is, of course, a tool for very accurate measurement, so I think the accuracy of the figure makes sense in this case.

  • You changed \startrange from 0 to 1 in first diagram, so the range goes from 1 to 18, but in the question it goes from 0 to 17 just as in my answer. For the second diagram I chose another range as in the quesiton, just to show the dynamic of the vertical scale. Your second adaption is to move the horizontal axis away from the vertical center? So to match the figure of the question one could move the y-coordinates by +0.08, but I thought it would be more "accurate" to assume the horizontal scale should be centered. For such a tiny change a comment would certainly have been sufficient. – dexteritas Feb 9 at 19:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.