Dimensioning of a technical drawing in TikZ
-- New -- Horizontal and vertical cotations.
\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
}
}
\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[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] {#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}
\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) ;
\Cote{(A)}{(B)}{1}
\Cote{(B)}{(C)}{2}[red]
\Cote[.3cm]{(B)}{(C)}{2}[%
red,Cote node/.append style={sloped}]]
\Cote{(B)}{(C)}{2 bis}<h>[Cote node/.append style={fill=blue!25}]
\Cote[.3cm]{(C)}{(D)}{3 bis}[%
Cote node/.append style={rotate=-90}]
\Cote[.7cm]{(C)}{(D)}{3}
\Cote[1.1cm]{(C)}{(D)}{3 ter}[%
Cote node/.append style={right}]
\Cote[2cm]{(G)}{(E)}{?$^\circ$}<(F)>
\Cote*[1.2cm]{(2.11,3.9)}{(2.89,3.9)}{4}[%
Cote node/.append style={left=.6cm,fill=blue!25}]
\Cote[-2cm]{(A)}{(2.5,4.29)}{5}<v>
\end{tikzpicture}
\bigskip
\begin{tikzpicture}
\draw[thick,blue,fill=blue!25]
(0,0) coordinate (A)
-- (2,2) coordinate (B)
-- (2,4) coordinate (C)
-- (0,2) coordinate (D)
--cycle ;
\Cote[.5]{(A)}{(B)}{5}<H>
\Cote[.5]{(D)}{(C)}{5}<V>
\end{tikzpicture}
\end{document}
I don't know about any library which allows dimensions to be easily added to technical drawings in TikZ. You can however add some manually. Simple rectangle and circles could be done using nodes which simplifies the drawing of additional material because the node anchors can be used. Differently shaped objects must be drawn using polygons.
Here an example of how to might be done. I can image some macros which take two points/coordiantes and some options like direction (left, right, above, below) and distance and then draw the dimension labels automatically. Wouldn't be that hard to code.
\usepackage{tikz}
\usetikzlibrary{patterns}
\usetikzlibrary{arrows}
% Adapted from the 'patterns' library: enlarged the distance between the lines from 4pt to 10pt
\pgfdeclarepatternformonly{north east lines wide}{\pgfqpoint{-1pt}{-1pt}}{\pgfqpoint{10pt}{10pt}}{\pgfqpoint{9pt}{9pt}}%
{
\pgfsetlinewidth{0.4pt}
\pgfpathmoveto{\pgfqpoint{0pt}{0pt}}
\pgfpathlineto{\pgfqpoint{9.1pt}{9.1pt}}
\pgfusepath{stroke}
}
\tikzset{%
body/.style={inner sep=0pt,outer sep=0pt,shape=rectangle,draw,thick,pattern=north east lines wide},
dimen/.style={<->,>=latex,thin,every rectangle node/.style={fill=white,midway,font=\sffamily}},
symmetry/.style={dashed,thin},
}
\begin{document}
\begin{tikzpicture}
% A body
\node [body,minimum height=4cm,minimum width=1.5cm,anchor=south west] (body1) at (0,0) {};
% Dimensions
\draw (body1.south west) -- ++(-1,0) coordinate (D1) -- +(-5pt,0);
\draw (body1.north west) -- ++(-1,0) coordinate (D2) -- +(-5pt,0);
\draw [dimen] (D1) -- (D2) node {4.00};
% Helper nodes can be reused
\draw (body1.south west) -- ++(0,-1) coordinate (D1) -- +(0,-5pt);
\draw (body1.south east) -- ++(0,-1) coordinate (D2) -- +(0,-5pt);
\draw [dimen] (D1) -- (D2) node {1.50};
% Non-rectangle shapes must be drawn as polygone
\begin{scope}[shift={(3,0)}]
\draw [body] (0,0) -- (0,4) -- (.5,4) -- (.5,5) -- (1.,5) -- (1.,4) -- (1.5,4) -- (1.5,0) -- cycle;
% Draw symmetry lines
\draw [symmetry] (.75,-.25) -- (.75,5.25);
% Dimensions
\draw (1.5,0) -- ++(1,0) coordinate (D1) -- +(5pt,0);
\draw (1.5,4) -- ++(1,0) coordinate (D2) -- +(5pt,0);
\draw [dimen] (D1) -- (D2) node {4.00};
\draw (0.0,0) -- ++(0,-1) coordinate (D1) -- +(0,-5pt);
\draw (1.5,0) -- ++(0,-1) coordinate (D2) -- +(0,-5pt);
\draw [dimen] (D1) -- (D2) node {1.50};
\draw (0.5,5) -- ++(0,1) coordinate (D1) -- +(0,5pt);
\draw (1.0,5) -- ++(0,1) coordinate (D2) -- +(0,5pt);
\draw [dimen,-] (D1) -- (D2) node [above=5pt] {0.50};
\draw [dimen,<-] (D1) -- ++(-5pt,0);
\draw [dimen,<-] (D2) -- ++(+5pt,0);
\end{scope}
\end{tikzpicture}
\end{document}
Result:
Here is a quick solution extending Jake's work on this question:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows,calc,decorations.markings}
\begin{document}
\pgfarrowsdeclarecombine{|<}{>|}{|}{|}{latex}{latex}
\def\Dimline[#1][#2][#3]{
\begin{scope}[>=latex] % redef arrow for dimension lines
\draw let \p1=#1, \p2=#2, \n0={veclen(\x2-\x1,\y2-\y1)} in [|<->|,
decoration={markings, % switch on markings
mark=at position .5 with {\node[#3] at (0,0) {\DimScale{\n0}};},
},
postaction=decorate] #1 -- #2 ;
\end{scope}
}
%% The following macro is used to scale a dimension from points to the
%% display scale. The following code divides the number of points by
%% 28.4 to roughly get the width in centimeters (rounding to the
%% nearest millimeter):
\def\DimScale#1{\pgfmathparse{round(#1/28.4*10.0)/10.0}\pgfmathresult cm}
\begin{tikzpicture}
\node at (0,0) (nA) {A};
\node at (3,0) (nB) {B};
\Dimline[($(nA)+(0,1)$)][($(nB)+(0,1)$)][above];
\node at (0,-3) (nC) {C};
\Dimline[($(nA)+(-1,0)$)][($(nC)+(-1,0)$)][left];
\Dimline[($(nC)+(0.3,-0.3)$)][($(nB)+(0.3,-0.3)$)][right];
\node at (3,-3) (nD) {D};
\Dimline[($(nC)+(0,-1)$)][($(nD)+(0,-1)$)][below];
\Dimline[($(nB)+(1,0)$)][($(nD)+(1,0)$)][right];
\end{tikzpicture}
\end{document}
Basically, what is going on here is we are automatically calculating the distance between points in units of pt
by using PGF/TikZ's veclen
function. My new macro \DimScale
then converts that length into centimeters (you could of course change it to convert to whichever units you want). Here is the result: