5

I try to make a fine macro to display the dimensions of lines inside a technical figure. This problem appears in several questions and answers but I would like to add some refinements. The next code is based on several codes and actually I have this :

\documentclass{scrartcl}
\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}{\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,#3}{%
                decoration = {add dim,distance=#2},
                decorate,
                postaction = {%
                   decorate,
                   decoration={%
                        markings,
                        mark=at position .5 with {\node[inner sep=0pt,
                                                        font=\footnotesize,
                                                        fill=white,
                                                        #3] at (0,0) {#1};}
                      }}}}

\tikzset{dim sloped/.style args={#1,#2}{%
                decoration = {add dim,distance=#2},
                decorate,
                postaction = {%
                   decorate,
                   decoration={%
                              text along path,
                              raise      = 3pt+\pgfkeysvalueof{/pgf/decoration/distance},
                              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,above=12pt}]   (A) --  (B);
\draw[dim sloped={7 cm,10pt}]  (B) --  (C); 

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

\end{document} 

enter image description here

The result is fine and it's what I want. Perhaps it's possible to add some styles to get something more friendly but now the problems :

1) With dim it's possible to write dim={,10pt,} but in this case I get a small white blank space on the main line. I can write \draw[dim={,10pt,above=12pt}] but it's not funny

2) If I can write dim={,10pt,}, I can't write \draw[dim={5 cm, ,above=12pt}]. I get the error "a number is missing". How to use the default or initial value of distance in this case ?

3) If it was possible to write \draw[dim={,,}] then I think it would be more fine to write \draw[dim={}] or perhaps \draw[dim=] . Perhaps something like \draw[dim default] is necessary ?

4) I would to have only one key like dim and not two keys with dim sloped but I try without success to modify one of theses keys. This is not very important because the mixt is a very bad thing. Sloped or not sloped , the user of the key needs to make a choice ! but i would to know if there is a solution.

4
  • 1
    1) You can set the fill to empty if there is no text: fill=\ifx&#1&none\else white\fi.
    – Jake
    May 12, 2012 at 18:04
  • 1
    2) The same approach works here: \ifx&#2&0pt\else#2\fi
    – Jake
    May 12, 2012 at 18:10
  • @Jake It's not the most important part of the question but you can transform your comment in an answer, I would be be happy to upvote. May 12, 2012 at 18:10
  • 3) If you set dim/.default={,0pt,}, you can just call \draw [dim] .... Is that what you're looking for, or am I misunderstanding your question?
    – Jake
    May 12, 2012 at 18:12

1 Answer 1

8
  1. You can set the fill to empty if there is no text: fill=\ifx&#1&none\else white\fi.
  2. Similarly, you can define the distance to be 0pt if no distance is specified: distance=\ifx&#2&0pt\else#2\fi.
  3. To be able to call dim without specifying any options, you can set the .default: dim/.default={,0pt,}.
  4. You don't need to use the text along path decoration for sloped text along a straight line: You can just supply transform shape to the node of the markings decoration.

\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}{\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,#3}{%
                decoration = {add dim,distance=\ifx&#2&0pt\else#2\fi},
                decorate,
                postaction = {%
                   decorate,
                   decoration={%
                        raise=\ifx&#2&0pt\else#2\fi,
                        markings,
                        mark=at position .5 with {\node[inner sep=0pt,
                                                        font=\footnotesize,
                                                        fill=\ifx&#1&none\else white\fi,
                                                        #3] at (0,0) {#1};}
                   }
                }
    },
    dim/.default={,0pt,}
}


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

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

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

\end{document} 
2
  • transform shape is a fine idea but why ? what is the explanation ? May 12, 2012 at 18:48
  • 1
    @Altermundus: By default, only translations apply to nodes, but not other transformations like scaling or rotating. If you set transform shape, the rotation of the coordinate system that is set up by the markings decoration also applies to the node.
    – Jake
    May 12, 2012 at 18:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .