10

I want to create a LaTeX package called for example dimension to provided a tikz style option named for example dimstyle.

Then given two points A and B we can use this style to draw a dimension line that shows the distance between the two points.

It is not needed to calculate this distance from the coordinates of the two points.

\usetikzlibrary{dimension}
\begin {tikzpicture}
   \coordinate (A) at (0,0);
    \coordinate (B) at (4,3);

   \draw [dimstyle] (A)--(B);
\end {tikzpicture}

enter image description here

In this picture, all the drawing except the two circles and the two characters A and B is referred as a dimension line which shows the distance between the two circles.

6
  • This is not really a line between (A) and (B) to use (A)--(B). I suggest another notation to keep original tikz clear. Also I think a newcommand would be possibly a better option than a style... And last: do you mean (A) at (0,0) and (B) at (6,8)? (this gives distance 10) or you mean that you will provide the length with another way?
    – koleygr
    Commented Feb 27, 2018 at 18:39
  • the line is not between A and B but I suppose we can use a shift option with (A)--(B). Commented Feb 27, 2018 at 19:22
  • yes the length may be provided textually. Commented Feb 27, 2018 at 19:24
  • So the small circles are not the points... Please make more clear your needs... I suppose anyone of us thought that te dots was the points... Try to make clear your specific needs before someone post an answer and have to change again and again (can add a grid for example, give directions on where the points and the length should be placed (eg: east and west, or right and left, or manually [an option]))... Try to make really clear what you want.
    – koleygr
    Commented Feb 27, 2018 at 19:27
  • 1
    Either a to path or a show path construction. See also the source code of decoration=brace (line 140 of pgflibrarydecorations.pathreplacing.code.tex)
    – Symbol 1
    Commented Feb 27, 2018 at 19:35

3 Answers 3

5

I start a new answer because I made a pgfkey frontend to the cotation macro. In the example I put syntaxes in parallel.

enter image description here

\documentclass{article}
\usepackage{xparse,tikz}
\usetikzlibrary{calc}

\RequirePackage{pdftexcmds}
\makeatletter
\let\pdfstrcmp\pdf@strcmp
\let\pdffilemoddate\pdf@filemoddate

\tikzset{%
    Cote node/.style={%
        midway,
        %sloped,
        fill=white,
        inner sep=1.5pt,
        outer sep=2pt
    },
    Cote arrow/.style={%
        <->,
        >=latex,
        very thin
    },
    Cote lines/.style={%
        very thin
    },
    Cote/.style={to path={\pgfextra{
        \pgfinterruptpath
        \ifCoteOut
        \expandafter\Cote\expandafter*\expandafter[\expandafter\@offset\expandafter]\expandafter{\expandafter(\expandafter\tikztostart\expandafter)\expandafter}\expandafter{\expandafter(\expandafter\tikztotarget\expandafter)\expandafter}\expandafter{\expandafter\@text\expandafter}\expandafter<\@aspect>
        \else
        \expandafter\Cote\expandafter[\expandafter\@offset\expandafter]\expandafter{\expandafter(\expandafter\tikztostart\expandafter)\expandafter}\expandafter{\expandafter(\expandafter\tikztotarget\expandafter)\expandafter}\expandafter{\expandafter\@text\expandafter}\expandafter<\@aspect>
        \fi
        \endpgfinterruptpath
        }(\tikztostart) -- (\tikztotarget) \tikztonodes}}
}

\newif\ifCoteOut

\pgfkeys{tikz/Cote/.cd,
    offset/.store in=\@offset,
    offset=.75cm,
    text/.store in=\@text,
    text=,
    aspect/.store in=\@aspect,
    aspect=o,
    Cote out/.is if=CoteOut,
    Cote out=false,
} 
\makeatletter

\NewDocumentCommand{\Cote}{%
    s       % cotation avec les flèches à l'extérieur
    D<>{1.5pt} % offset des traits
    O{.75cm}    % offset de cotation
    m       % premier point
    m       % second point
    m       % étiquette
    D<>{o}  % () coordonnées -> angle
            % h -> horizontal,
            % v -> vertical
            % o or what ever -> oblique
    O{}     % parametre du tikzset
    }{%

    {\tikzset{#8}

    \coordinate (@1) at #4 ;
    \coordinate (@2) at #5 ;

    \if #7H % Cotation traits horizontaux
        \coordinate (@0) at ($($#4!.5!#5$) + (#3,0)$) ; 
        \coordinate (@5) at ($#5+(#3,0)$) ;
        \coordinate (@4) at ($#4+(#3,0)$) ;
    \else
    \if #7V % Cotation traits verticaux
        \coordinate (@0) at ($($#4!.5!#5$) + (#3,0)$) ; 
        \coordinate (@5) at ($#5+(0,#3)$) ;
        \coordinate (@4) at ($#4+(0,#3)$) ;
    \else
    \if #7v % Cotation verticale
        \coordinate (@0) at ($($#4!.5!#5$) + (#3,0)$) ; 
        \coordinate (@4) at (@0|-@1) ;
        \coordinate (@5) at (@0|-@2) ;
    \else
    \if #7h % Cotation horizontale
        \coordinate (@0) at ($($#4!.5!#5$) + (0,#3)$) ; 
        \coordinate (@4) at (@0-|@1) ;
        \coordinate (@5) at (@0-|@2) ;
    \else % cotation encoche
    \ifnum\pdfstrcmp{\unexpanded\expandafter{\@car#7\@nil}}{(}=\z@
        \coordinate (@5) at ($#7!#3!#5$) ;
        \coordinate (@4) at ($#7!#3!#4$) ;
    \else % cotation oblique    
        \coordinate (@5) at ($#5!#3!90:#4$) ;
        \coordinate (@4) at ($#4!#3!-90:#5$) ;
    \fi\fi\fi\fi\fi

    \draw[Cote lines,shorten >= #2,shorten <= -2*#2] (@4) -- #4 ;
    \draw[Cote lines,shorten >= #2,shorten <= -2*#2] (@5) -- #5 ;

    \IfBooleanTF #1 {% avec étoile
    \draw[Cote arrow,-] (@4) -- (@5) node[Cote node] {#6\strut};
    \draw[Cote arrow,<-] (@4) -- ($(@4)!-6pt!(@5)$) ;   
    \draw[Cote arrow,<-] (@5) -- ($(@5)!-6pt!(@4)$) ;   
    }{% sans étoile
    \ifnum\pdfstrcmp{\unexpanded\expandafter{\@car#7\@nil}}{(}=\z@
        \draw[Cote arrow] (@5) to[bend right]
            node[Cote node] {#6\strut} (@4) ;
    \else
    \draw[Cote arrow] (@4) -- (@5) node[Cote node] {#6\strut};
    \fi
    }}
    }

\makeatother

\begin{document}
\begin {tikzpicture}[font=\sf]
\small
\draw[thick,blue,fill=blue!25]
        (0,1) coordinate (A)
    --  (3,1) coordinate (B)
    --  (5,2) coordinate (C)
    --  (5,4) coordinate (D)
    --  (3,4) coordinate (E)
    --  (2.5,3) coordinate (F)
    --  (2,4) coordinate (G)
    --  (0,4) coordinate (H)
    --cycle ;

\draw[red,fill=red!25] (2.5,3.9) circle (.39) ;

% macro version
%\Cote{(A)}{(B)}{1}

\path[Cote/.cd,
text={1},           % cotation text - distance if empty
] (A) to[Cote] (B) ;

%\Cote{(B)}{(C)}{2}[red] % macro version

\path[red,  % pass general options to local tikzset
Cote/.cd,
text={2},
] (B) to[Cote] (C) ;

% macro version
%\Cote[.3cm]{(B)}{(C)}{2}[%
%   red,Cote node/.append style={sloped}]]

\path[red,Cote node/.append style={sloped},
Cote/.cd,
offset=.3cm,        % change offset
text={2},
] (B) to[Cote] (C) ;

%\Cote{(B)}{(C)}{2 bis}<h>[Cote node/.append style={fill=blue!25}]

\path[red,Cote node/.append style={fill=blue!25},
Cote/.cd,
text={2 bis},
aspect=h,   % h horizontal node even if path not
] (B) to[Cote] (C) ;

% macro version
%\Cote[.7cm]{(C)}{(D)}{3}

\path[Cote/.cd,
offset=.7cm,
text={3},
] (C) to[Cote] (D) ;

% macro version
%\Cote[.3cm]{(C)}{(D)}{3 bis}[%
%       Cote node/.append style={rotate=-90}]

\path[Cote node/.append style={rotate=90},
Cote/.cd,
offset=.3cm,
text={3 bis},
] (C) to[Cote] (D) ;

% macro version
%\Cote[1.1cm]{(C)}{(D)}{3 ter}[%
%           Cote node/.append style={right}]

% macro version
\path[Cote node/.append style={right},
Cote/.cd,
offset=1.1cm,
text={3 ter},
] (C) to[Cote] (D) ;

% macro version
%\Cote[2cm]{(G)}{(E)}{?$^\circ$}<(F)>

% #### ###########  problem here
\path[Cote/.cd,
offset=2cm,
aspect=(F), % <- the left parenthesis seem not to bee seen in the test above
text={?$^\circ$},
] (G) to[Cote] (E) ;

% macro version
% \Cote*[1.2cm]{(2.11,3.9)}{(2.89,3.9)}{4}[
% Cote node/.append style={left=.6cm,fill=blue!25}]

\path[Cote node/.append style={left=.6cm,fill=blue!25},
Cote/.cd,
offset=1.2cm,
text={4},
Cote out=true,  % external cotation
] (2.11,3.9) to[Cote] (2.89,3.9) ;

% macro version
%\Cote[-2cm]{(A)}{(2.5,4.29)}{5}<v>

\path[Cote/.cd,
offset=-2cm,
text={5},
aspect=v,
] (A) to[Cote] (2.5,4.29) ;


\begin{scope}[yshift=-5cm]
\draw[thick,blue,fill=blue!25]
    (0,0) coordinate (A)
--  (2,2) coordinate (B)
--  (2,4) coordinate (C)
--  (0,2) coordinate (D)
--cycle ;
\end{scope}

%\Cote[.5]{(A)}{(B)}{6}<H>
%\Cote[.5]{(D)}{(C)}{7}<V>

\path[Cote/.cd,
offset=.5cm,
text={6},
aspect=H,
] (A) to[Cote] (B) ;

\path[Cote/.cd,
offset=.5cm,
text={6},
aspect=V,
] (D) to[Cote] (C) ;

\end {tikzpicture}
\end{document}
3
  • \expandafter<\expandafter\@aspect> would be expanding >. For \@aspect remove one \expandafter: \expandafter<\@aspect> Commented Feb 28, 2018 at 19:55
  • You diserve a bonus !
    – Tarass
    Commented Feb 28, 2018 at 20:00
  • I think that the following commands should be removed: \RequirePackage{pdftexcmds}, \let\pdfstrcmp\pdf@strcmp and \let\pdffilemoddate\pdf@filemoddate Commented Jun 19, 2018 at 21:32
8

3nd EDIT: I completely switched gears and just present a solution that is almost entirely taken from this cool answer. It allows you to control the distance of the measurement bar. The only thing I added is to store \pgfdecoratedpathlength in a macro that I use in the annotation. UPDATE: Changed the style such that by default no line is drawn.

\documentclass{article} % mostly taken from https://tex.stackexchange.com/a/37926/121799
\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}}
          \pgfextra{
            \pgfmathtruncatemacro{\MyLen}{round(10*\pgfdecoratedpathlength/28.45369)}
            \xdef\NewLen{\MyLen}
            }
}}

\tikzset{dim/.style args={#1}{draw=none,decoration={add dim,distance=#1},
                decorate,
                postaction={decorate,decoration={text along path,
                                                 raise=#1,
                                                 text align={align=center},
                                                 text={|\sf|$L=\NewLen$mm{}}}}}}


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

\draw[dim={10pt}]  (A) --  (B);
\draw[dim={-15pt},draw]  (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

7
  • With my poor english, I just understood the opposite. The OP wants the real lenght to be calculated, I just add this possibility. Silly me...
    – Tarass
    Commented Feb 27, 2018 at 21:37
  • @Tarass There is at least one more user who understood it in the way you did. ;-) Most likely a marriage of our two answers will make the OP happy. Do you want to go ahead? (My otherwise poor post shows how to attach the number when using a style, and the OP was asking for this.)
    – user121799
    Commented Feb 27, 2018 at 21:42
  • My idea is to get the coordinates of the extremities of the path, and then apply the macro principe using tikzkeys or pgfkeys. I try this ` \tikzset{Cote/.code={% \pgfextra{ \coordinate (@a) at (\the\pgf@pathminx/28.45369 cm,\the\pgf@pathminy/28.45369 cm) ; \coordinate (@b) at (\the\pgf@pathmaxx/28.45369 cm,\the\pgf@pathmaxy/28.45369 cm) ; } \draw (@a) -- (@b) ; }} ` but it is not working. I try different combination of cm ...
    – Tarass
    Commented Feb 27, 2018 at 22:12
  • postaction helps only for the first coordinate...
    – Tarass
    Commented Feb 27, 2018 at 22:31
  • @Tarass I am sorry, I was busy and could not understand what you are saying. But you can take over, I am done for now. And I have a vague idea how an elegant solution will work, but no time to work it out at the moment.
    – user121799
    Commented Feb 28, 2018 at 0:26
6

Whit this Dimensioning of a technical drawing in TikZ and a little add one can do :

If the cotation parameter is empty, the macro displays the real length.

enter image description here

\documentclass{article}
\usepackage{xparse,tikz}
\usetikzlibrary{calc}
\RequirePackage{ifluatex}

\makeatletter

\ifluatex
\RequirePackage{pdftexcmds}
\let\pdfstrcmp\pdf@strcmp
\let\pdffilemoddate\pdf@filemoddate
\fi

\tikzset{%
    Cote node/.style={%
        midway,
        %sloped,
        fill=white,
        inner sep=1.5pt,
        outer sep=2pt
    },
    Cote arrow/.style={%
        <->,
        >=latex,
        very thin
    }
}

\makeatletter
\NewDocumentCommand{\Cote}{%
    s       % cotation avec les flèches à l'extérieur
    D<>{1.5pt} % offset des traits
    O{.75cm}    % offset de cotation
    m       % premier point
    m       % second point
    m       % étiquette
    D<>{o}  % () coordonnées -> angle
            % h -> horizontal,
            % v -> vertical
            % o or what ever -> oblique
    O{}     % parametre du tikzset
    }{%

    {\tikzset{#8}

    \ifx\hfuzz#6\hfuzz
        \coordinate (@a) at #4 ;
        \coordinate (@b) at #5 ;
        \pgfpointdiff{\pgfpointanchor{@a}{center}}{\pgfpointanchor{@b}{center}}
        % no need to use a new dimen
        \pgf@xa=\pgf@x
        \pgf@ya=\pgf@y
        % to convert from pt to cm   
        \pgfmathsetmacro{\@et}{veclen(\pgf@xa,\pgf@ya)/28.45274}
    \else
        \edef\@et{#6}
    \fi

    \coordinate (@1) at #4 ;
    \coordinate (@2) at #5 ;

    \if #7H % Cotation traits horizontaux
        \coordinate (@0) at ($($#4!.5!#5$) + (#3,0)$) ; 
        \coordinate (@5) at ($#5+(#3,0)$) ;
        \coordinate (@4) at ($#4+(#3,0)$) ;
    \else
    \if #7V % Cotation traits verticaux
        \coordinate (@0) at ($($#4!.5!#5$) + (#3,0)$) ; 
        \coordinate (@5) at ($#5+(0,#3)$) ;
        \coordinate (@4) at ($#4+(0,#3)$) ;
    \else
    \if #7v % Cotation verticale
        \coordinate (@0) at ($($#4!.5!#5$) + (#3,0)$) ; 
        \coordinate (@4) at (@0|-@1) ;
        \coordinate (@5) at (@0|-@2) ;
    \else
    \if #7h % Cotation horizontale
        \coordinate (@0) at ($($#4!.5!#5$) + (0,#3)$) ; 
        \coordinate (@4) at (@0-|@1) ;
        \coordinate (@5) at (@0-|@2) ;
    \else % cotation encoche
    \ifnum\pdfstrcmp{\unexpanded\expandafter{\@car#7\@nil}}{(}=\z@
        \coordinate (@5) at ($#7!#3!#5$) ;
        \coordinate (@4) at ($#7!#3!#4$) ;
    \else % cotation oblique    
        \coordinate (@5) at ($#5!#3!90:#4$) ;
        \coordinate (@4) at ($#4!#3!-90:#5$) ;
    \fi\fi\fi\fi\fi

    \draw[very thin,shorten >= #2,shorten <= -2*#2] (@4) -- #4 ;
    \draw[very thin,shorten >= #2,shorten <= -2*#2] (@5) -- #5 ;

    \IfBooleanTF #1 {% avec étoile
    \draw[Cote arrow,-] (@4) -- (@5)
        node[Cote node] {\@et\strut};
    \draw[Cote arrow,<-] (@4) -- ($(@4)!-6pt!(@5)$) ;   
    \draw[Cote arrow,<-] (@5) -- ($(@5)!-6pt!(@4)$) ;   
    }{% sans étoile
    \ifnum\pdfstrcmp{\unexpanded\expandafter{\@car#7\@nil}}{(}=\z@
        \draw[Cote arrow] (@5) to[bend right]
            node[Cote node] {\@et\strut} (@4) ;
    \else
    \draw[Cote arrow] (@4) -- (@5)
        node[Cote node] {\@et\strut};
    \fi
    }}
    }

\makeatother

\begin{document}
\begin {tikzpicture}[font=\sf]
\fill (0,0) coordinate (A) circle (1pt) node[anchor=north west] {A};
\fill (2,3) coordinate (B) circle (1pt) node[anchor=north west] {B};

\Cote[.3]{(B)}{(A)}{}[Cote node/.append style={sloped}]
\Cote[.1]{(B)}{(A)}{L=10}[Cote node/.append style={sloped}]

\end {tikzpicture}
\end{document}
7
  • This solution seems fine. However I wonder if the same task can be achieved by defining a style ? Commented Feb 27, 2018 at 21:26
  • Can we take off the arrows to get something similar to the picture provided within the question's body Commented Feb 27, 2018 at 21:34
  • Yes, with pgfkeys for example.
    – Tarass
    Commented Feb 27, 2018 at 21:34
  • There is a Cote arrow style in the tikset, you can adapt it as you want. I have note the time now to reformule the macro to a style. But I will.
    – Tarass
    Commented Feb 27, 2018 at 21:40
  • That would be very helpful for me if you show me how to define a style. Thanks! Commented Feb 28, 2018 at 8:32

You must log in to answer this question.

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