26

Is it possible to define in TikZ a new decoration or something like that, such that it is possible to write something like:

\draw[dim={text,above}] (A) -- (B);
\draw[dim={text,below}] (C) -- (D);

or even better

\draw (A) dim[text,above] (B);
\draw (C) dim[text,below] (C);

to get something like this:

dim

It's important that the text is sloped.

If possible I would prefer the second syntax, because then I could easily combine such path's:

\draw (A) dim[text,above] (B) -- (C) -- (D) dim[text] (E) dim[text,below] (F) -- circle;
  • possible duplicate of Dimensioning of a technical drawing in TikZ – Jake Dec 11 '11 at 12:34
  • 1
    It's not a duplicate because the object I want is slightly different, because I want a special syntax and because I want to have the label sloped – student Dec 11 '11 at 12:53
  • I agree that it isn't a duplicate, just a related question. Having a dim option might be possible, but having a dim path command is not possible (as long you don't rewrite TikZ internal path parser). – Martin Scharrer Dec 11 '11 at 12:59
  • You can also do this via defining a new decoration with |-| type of arrows. See this question "Line segments with text in the middle in TikZ" and answers for different solutions. – percusse Dec 11 '11 at 17:19
  • @percusse But how to get the double lines for my case? – student Dec 11 '11 at 17:37
27

Update

The result looks fine but perhaps the code can be improved.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations,decorations.markings,decorations.text}

\begin{document}
 \pgfkeys{/pgf/decoration/.cd,
      distance/.initial=10pt
}  

\pgfdeclaredecoration{add dim}{final}{
\state{final}{% 
\pgfmathsetmacro{\dist}{5pt*\pgfkeysvalueof{/pgf/decoration/distance}/abs(\pgfkeysvalueof{/pgf/decoration/distance})}    
          \pgfpathmoveto{\pgfpoint{0pt}{0pt}}             
          \pgfpathlineto{\pgfpoint{0pt}{2*\dist}}   
          \pgfpathmoveto{\pgfpoint{\pgfdecoratedpathlength}{0pt}} 
          \pgfpathlineto{\pgfpoint{(\pgfdecoratedpathlength}{2*\dist}}     
          \pgfsetarrowsstart{latex}
          \pgfsetarrowsend{latex}
          \pgfpathmoveto{\pgfpoint{0pt}{\dist}}
          \pgfpathlineto{\pgfpoint{\pgfdecoratedpathlength}{\dist}} 
          \pgfusepath{stroke} 
          \pgfpathmoveto{\pgfpoint{0pt}{0pt}}
          \pgfpathlineto{\pgfpoint{\pgfdecoratedpathlength}{0pt}}
}}

\tikzset{dim/.style args={#1,#2}{decoration={add dim,distance=#2},
                decorate,
                postaction={decorate,decoration={text along path,
                                                 raise=#2,
                                                 text align={align=center},
                                                 text={#1}}}}}

\begin{tikzpicture}
\coordinate (A) at (0,0);
\coordinate (B) at (4,2);
\coordinate (C) at (8,-2);

\draw[dim={5 cm,10pt}]  (A) --  (B);
\draw[dim={7 cm,-15pt}]  (B) --  (C); 

\draw[fill=gray] (A) circle(2pt); 
\draw[fill=gray] (B) circle(2pt);
\draw[fill=gray] (C) circle(2pt);    
\end{tikzpicture}

\end{document}

enter image description here

Update : possible with edge

\draw (A) edge [dim={5 cm,10pt}]  (B) 
          edge[dim={7 cm,-15pt}]  (C)
       (B)edge[dim={4 cm,+10pt}]  (C);  

enter image description here

  • 1
    Great. Is it possible to adjust this such that one can write something like \draw (A) dim[text,above] (B) -- (C) -- (D) dim[text] (E) dim[text,below] (F) -- circle; – student Dec 11 '11 at 19:38
  • @user4011 No it's impossible because decoration is applied to the whole path; you can use edge like in my update code. – Alain Matthes Dec 11 '11 at 20:22
  • Alain, thanks for this great answer. However, I cannot label the dimension line with a mathematical symbol. As soon as type in $a$ for exmaple, the macro does weird stuff. Is there any way to fix this? – Ingo Jun 5 '13 at 8:13
  • I'm using pdflatex and had to terminate the application manually after passing a math symbol to the macro as a label... – John Chris Nov 21 '14 at 16:51
  • @AlainMatthes can you fix some problem in your sty. Here is the link in my question. tex.stackexchange.com/questions/381401/… – Le Quan Plus Jul 20 '17 at 8:23
11

Here is a solution, via to path, that allows to use the second required syntax:

enter image description here

\documentclass[tikz,margin=2mm]{standalone}
\usetikzlibrary{calc}
\tikzset{
  dim above/.style={to path={\pgfextra{
        \pgfinterruptpath
        \draw[>=latex,|<->|] let
        \p1=($(\tikztostart)!2mm!90:(\tikztotarget)$),
        \p2=($(\tikztotarget)!2mm!-90:(\tikztostart)$)
        in(\p1) -- (\p2) node[pos=.5,sloped,above]{#1};
        \endpgfinterruptpath
      }(\tikztostart) -- (\tikztotarget) \tikztonodes
    }
  },
  dim below/.style={to path={\pgfextra{
        \pgfinterruptpath
        \draw[>=latex,|<->|] let 
        \p1=($(\tikztostart)!2mm!90:(\tikztotarget)$),
        \p2=($(\tikztotarget)!2mm!-90:(\tikztostart)$)
        in (\p1) -- (\p2) node[pos=.5,sloped,below]{#1};
        \endpgfinterruptpath
      }(\tikztostart) -- (\tikztotarget) \tikztonodes
    }
  },
}

\begin{document}
\begin{tikzpicture}
  \draw (0,0) to[dim above=text] (4,-2) to[dim below=other text](0,-4);
\end{tikzpicture}
\end{document}
10

In the interim, for whomever might be interested in a pstricks version of this style, which presents a pretty straight-forward way of rotating text labels between paths:

enter image description here

\documentclass{article}
\usepackage{pstricks,pstricks-add}% http://www.tug.org/PSTricks/main.cgi/
\begin{document}
\begin{pspicture}(10,5)
  \pcline{-}(0,0)(3,2)
  \pcline[offset=12pt]{|-|}(0,0)(3,2)
  \ncput*[nrot=:U]{Length}

  \pcline{-}(5,1)(8,0)
  \pcline[offset=-12pt]{|<->|}(5,1)(8,0)
  \nbput[nrot=:U]{Text}
\end{pspicture}
\end{document}

It requires the traditional latex -> dvips -> ps2pdf or xelatex compiling sequence (unless you're using auto-pst-pdf).

  • |<*->|* and |*-|* give more precise ends. – kiss my armpit Nov 13 '13 at 5:11

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.