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.

  • 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 Feb 27 '18 at 18:39
  • the line is not between A and B but I suppose we can use a shift option with (A)--(B). – Hafid Boukhoulda Feb 27 '18 at 19:22
  • yes the length may be provided textually. – Hafid Boukhoulda Feb 27 '18 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 Feb 27 '18 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 Feb 27 '18 at 19:35
  • @HafidBoukhoulda I add the possibilty of an emp ty cotation parameter that display the real length. I you did, I can define a macro whith this length. – Tarass Feb 27 '18 at 21:24

3 Answers3

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

  • 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 Feb 27 '18 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.) –  Feb 27 '18 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 Feb 27 '18 at 22:12
  • postaction helps only for the first coordinate... – Tarass Feb 27 '18 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. –  Feb 28 '18 at 00:26
  • I change the approach : https://tex.stackexchange.com/questions/417694/how-to-store-pgfkeys-in-the-good-directory – Tarass Feb 28 '18 at 08:27
  • @marmot Is it possible with this solution to not to draw the lines between each circle? Please see the picture provided within the question's body. Thank you! – Hafid Boukhoulda Feb 28 '18 at 08:46
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}
Tarass
  • 16,912
  • This solution seems fine. However I wonder if the same task can be achieved by defining a style ? – Hafid Boukhoulda Feb 27 '18 at 21:26
  • Can we take off the arrows to get something similar to the picture provided within the question's body – Hafid Boukhoulda Feb 27 '18 at 21:34
  • Yes, with pgfkeys for example. – Tarass Feb 27 '18 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 Feb 27 '18 at 21:40
  • That would be very helpful for me if you show me how to define a style. Thanks! – Hafid Boukhoulda Feb 28 '18 at 08:32
  • @HafidBoukhoulda look at the begining of my code, you see tikzset and after a style declaration, then the style définitition. Did you see it ? – Tarass Feb 28 '18 at 08:34
  • Yes I see it! If I have understood correctly ,the two styles affect the text added in the middle and also affect the type of the arrows used . But how can we use a style to add the lines at the limit of the arrows? – Hafid Boukhoulda Feb 28 '18 at 09:02
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}
Tarass
  • 16,912