我正在使用 tikz,想绘制一些直线段,使得线段的两端都有 5pt 点,其余部分为空白。在纯文本中,它将类似于
xxx-----------------xxx
我不想计算发生变化的中间点,除非说它与两端的距离是固定的。
谢谢,V。
答案1
下面是箭头的实现,类似于如何绘制以省略号结尾的线条?\pgfsetarrowoptions
但是使用 和的帮助实现了选项\pgfgetarrowoptions
,尽管您不需要使用它们,因为我添加了三个 TikZ 键:
dotted arrow length
:“箭头”的长度,我猜这是你的5pt
。dotted arrow pattern
:用于划线的图案。这可以通过以下三种方式之一使用(也在低级别上):
- 一单个 TikZ 键类似
dotted
(它实际上可以是任何 TikZ 键,但请不要......); dash pattern
像这样的设置on 2pt off 3pt on 4pt off 5pt
;- 像 这样的虚线
\pgfsetdash
图案规范{2pt}{3pt}{4pt}{pt}
。
- 一单个 TikZ 键类似
dotted arrow phase
:虚线图案的相位。如果为空,则将被忽略,除非\pgfsetdash
使用上面的规范,然后将其设置为+0pt
。
警告:由于箭头选项的实现方式 ( ),您不能在选项中\csname
使用(但是您可以使用and代替)。\pgflinewidth
dotted arrow pattern
\the\pgflinewidth
4*\the\pgflinewidth
4\pgflinewidth
不过,你可以用 TikZ 风格来隐藏它
\tikzset{
my dashing/.style={
dash pattern=on 4\pgflinewidth off 4\pgflinewidth}}
无论如何我都推荐它。
代码
\documentclass[tikz]{standalone}
\makeatletter
\def\pgfutil@firstofthree#1#2#3{#1}
\def\pgfutil@notfirstofthree#1#2#3{{#2}{#3}}
\def\pgfutil@replace@frstofthr#1#2#3#4{{#4}{#2}{#3}}
\def\pgfutil@replace@scndofthr#1#2#3#4{{#1}{#4}{#3}}
\def\pgfutil@replace@thrdofthr#1#2#3#4{{#1}{#2}{#4}}
\pgfarrowsdeclare{dotted}{dotted}{%
\edef\pgf@arrow@temp{\pgfgetarrowoptions{dotted}}%
\edef\pgf@arrow@temp{\expandafter\pgfutil@firstofthree\pgf@arrow@temp}%
\pgfarrowsleftextend{+0pt}%
\pgfarrowsrightextend{\pgf@arrow@temp}%
}{%
\edef\pgf@arrow@temp{\pgfgetarrowoptions{dotted}}%
\edef\pgf@temp{\expandafter\pgfutil@firstofthree\pgf@arrow@temp}%
\pgfpathmoveto{\pgfpointorigin}%
\pgfpathlineto{\pgfpoint{\pgf@temp}{0pt}}%
\edef\pgf@temp{\expandafter\expandafter\expandafter\pgfutil@firstoftwo\expandafter\pgfutil@notfirstofthree\pgf@arrow@temp}%
\pgfutil@ifundefined{pgfk@/tikz/\pgf@temp/.@cmd}{% is it a TikZ style?
\edef\pgf@temp{\expandafter\pgfutil@notfirstofthree\pgf@arrow@temp}%
\expandafter\pgf@handle@dottedoption\pgf@temp
}{%
\let\tikz@options\pgfutil@empty
\expandafter\tikzset\expandafter{\pgf@temp}%
\edef\pgf@temp{\expandafter\expandafter\expandafter\pgfutil@secondoftwo\expandafter\pgfutil@notfirstofthree\pgf@arrow@temp}%
\ifx\pgf@temp\pgfutil@empty\else
\edef\pgf@arrows@marshal{\noexpand\pgfkeysvalueof{/tikz/dash phase/.@cmd}\pgf@temp\noexpand\pgfeov}%
\pgf@arrows@marshal
\fi
\tikz@options
}%
\pgfusepathqstroke}
\def\pgf@handle@dottedoption#1#2{%
\pgfutil@in@{on}{#1}% maybe it is an "on 2pt off 3pt on 4pt off 5pt" setting?
\ifpgfutil@in@
\let\tikz@options\pgfutil@empty
\pgfkeysvalueof{/tikz/dash pattern/.@cmd}#1\pgfeov
\edef\pgf@temp{#2}%
\ifx\pgf@temp\pgfutil@empty\else
\pgfkeysvalueof{/tikz/dash phase/.@cmd}#2\pgfeov
\fi
\tikz@options
\else % so a low-level PGF setting? Okay ...
\edef\pgf@temp{#2}%
\ifx\pgf@temp\pgfutil@empty
\pgfsetdash{#1}{+0pt}%
\else
\pgfsetdash{#1}{#2}%
\fi
\fi}
\tikzset{
dotted arrow length/.code=%
\edef\tikz@temp{\pgfgetarrowoptions{dotted}}%
\edef\tikz@temp{\expandafter\pgfutil@replace@frstofthr\tikz@temp{#1}}%
\edef\tikz@marshal{\noexpand\pgfsetarrowoptions{dotted}{\tikz@temp}}%
\tikz@marshal,
dotted arrow pattern/.code=%
\edef\tikz@temp{\pgfgetarrowoptions{dotted}}%
\edef\tikz@temp{\expandafter\pgfutil@replace@scndofthr\tikz@temp{#1}}%
\edef\tikz@marshal{\noexpand\pgfsetarrowoptions{dotted}{\tikz@temp}}%
\tikz@marshal,
dotted arrow phase/.code=%
\edef\tikz@temp{\pgfgetarrowoptions{dotted}}%
\edef\tikz@temp{\expandafter\pgfutil@replace@thrdofthr\tikz@temp{#1}}%
\edef\tikz@marshal{\noexpand\pgfsetarrowoptions{dotted}{\tikz@temp}}%
\tikz@marshal}
\makeatother
\pgfsetarrowoptions{dotted}{{5pt}{densely dotted}{}}
\tikzset{thick}
\begin{document}
\begin{tikzpicture}[gridded]
\draw [dotted-dotted] (0,0) to[out=10,in=250] (2,2);
\end{tikzpicture}
\begin{tikzpicture}[every path/.append style={arrows=dotted-dotted},y=.2cm]
\draw (0,3) -- (3,3) [dotted arrow pattern=on .2pt off .2pt on .4pt off .4pt on .6pt off .6pt];
\draw (0,2) -- (3,2) [dotted arrow length=20pt, dotted arrow pattern=densely dashdotdotted];
\draw (0,1) -- (3,1) [dotted arrow length=20pt];
\draw (0,0) -- (3,0);
\end{tikzpicture}
\begin{tikzpicture}[dotted arrow pattern=dont try this at home, dotted arrow length=10pt, dont try this at home/.style={color=red,thick,dash phase=1pt,dotted}]
\draw[blue, line cap=round, ultra thick, dotted-dotted] (0,0) to[bend left=10] (2,0);
\end{tikzpicture}
\end{document}
输出
答案2
这里有两种简单的方法。一种是使用postaction
在虚线上方绘制实线,另一种是使用calc
库计算距离端点给定距离的点,并以这些点为起点绘制实线和虚线。
我把它包装在一个宏中,这样更容易使用。它可能可以被做成 TikZ 风格或其他风格,但我不知道怎么做。但它也不完美,因为端点可能是错误的(见下面的例子)。
\documentclass[border=2mm,tikz]{standalone}
\usetikzlibrary{calc}
\newcommand\dotandsolid[3][5pt]{%
\coordinate (startofsolidline) at ($(#2)!#1!(#3)$);
\coordinate (endofsolidline) at ($(#3)!#1!(#2)$);
\draw (startofsolidline) -- (endofsolidline);
\draw [densely dotted] (startofsolidline) -- (#2);
\draw [densely dotted] (endofsolidline) -- (#3);
}
\begin{document}
\begin{tikzpicture}
\draw [densely dotted,postaction={draw,solid,shorten >=5pt,shorten <=5pt}] (0,0) -- (1.5,0);
\dotandsolid{0,-0.2}{1.5,-.2}
\dotandsolid[0.5cm]{0,-.4}{1.5,-.4}
\end{tikzpicture}
\end{document}
答案3
另一种选择,通过命令;两端实线和第一个点之间的空间相等:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcommand\dotsoldot[3][]{%
\draw[shorten >=10pt,shorten <=10pt,#1] #2 -- #3;
\draw[dotted,#1] ($ #2!10pt!#3 $ ) -- ($ #2!0pt!#3 $ );
\draw[dotted,#1] ($ #3!10pt!#2 $ ) -- ($ #3!0pt!#2 $ );
}
\begin{document}
\begin{tikzpicture}
\dotsoldot{(0,0)}{(2.665,0)}
\dotsoldot[red,thick]{(1,2)}{(4,0)}
\end{tikzpicture}
\end{document}