答案1
我开始一个新的答案,因为我pgfkey
为 cotation 宏创建了一个前端。在示例中,我将语法并行化。
\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}
答案2
第三次编辑:我完全改变了思路,只提出了一个几乎完全取自于这个很酷的答案。它允许您控制测量条的距离。我添加的唯一内容是存储\pgfdecoratedpathlength
在注释中使用的宏中。更新:更改了样式,默认情况下不绘制线。
\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}
答案3
惠特TikZ 中的技术图纸尺寸标注并添加一点可以做的事情:
如果 cotation 参数为空,则宏显示实际长度。
\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}