我尝试根据 TikZ 中包含的菱形箭头制作倒菱形箭头,但我在将箭头尖端放在正确位置时遇到了很多麻烦。这是我的代码。我从钻石箭头代码是绘图代码。
\documentclass[tikz,border=0.25cm]{standalone}
\usetikzlibrary{arrows.meta}
\makeatletter
%\input{tikz_tips.tex}
\pgfdeclarearrow{
name = InvertedKite,
defaults = {
length = +3.6pt +5.4,
width' = +0pt +0.5,
inset' = +0pt 0.25,
line width = +0pt 1 1,
},
setup code = {
% Cap the line width at 1/4th of the length
\[email protected]\pgfarrowlength
\ifdim\pgf@x<\pgfarrowlinewidth
\pgfarrowlinewidth\pgf@x
\fi
\[email protected]\pgfarrowwidth
\ifdim\pgf@x<\pgfarrowlinewidth
\pgfarrowlinewidth\pgf@x
\fi
% Compute front miter length:
\pgf@xa\pgfarrowlength%
\advance\pgf@xa by-\pgfarrowinset%
\pgfmathdivide@\pgf@xa\pgfarrowwidth%
\let\pgf@temp@quot\pgfmathresult%
\pgf@x\pgfmathresult pt%
\pgf@x\pgfmathresult\pgf@x%
\pgf@x4\pgf@x%
\advance\pgf@x by1pt%
\pgfmathsqrt@\pgf@x%
\pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter
\[email protected]\pgf@xc
\pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter
% Compute back miter length:
\pgfmathdivide@\pgfarrowinset\pgfarrowwidth%
\let\pgf@temp@quot\pgfmathresult%
\pgf@x\pgfmathresult pt%
\pgf@x\pgfmathresult\pgf@x%
\pgf@x4\pgf@x%
\advance\pgf@x by1pt%
\pgfmathsqrt@\pgf@x%
\pgf@yc\pgfmathresult\pgfarrowlinewidth% yc is back miter
\[email protected]\pgf@yc
\pgf@ya\pgf@temp@quot\pgfarrowlinewidth% ya is extra harpoon miter
% Compute top miter length:
{%
\[email protected]\pgfarrowwidth%
\pgfutil@tempdima\pgfarrowlength\advance\pgfutil@tempdima by-\pgfarrowinset%
\csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfutil@tempdima}{\pgfmath@tonumber\pgfutil@tempdimb}%
\pgf@yb\pgfmathresult pt%
\csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfarrowinset}{\pgfmath@tonumber\pgfutil@tempdimb}%
\pgf@ya\pgfmathresult pt%
\advance\pgf@yb by\pgf@ya%
\[email protected]\pgf@yb% half angle in yb
\ifdim\pgf@yb=45pt%
\def\pgfmathresult{1.414213}%
\else%
\pgfmathsin@{\pgf@yb}%
\pgfmathreciprocal@{\pgfmathresult}%
\fi%
\pgf@yc\pgfmathresult\pgfarrowlinewidth%
\[email protected]\pgf@yc%
\pgf@ya-\pgf@ya%
\advance\pgf@ya by-90pt%
\advance\pgf@ya by\pgf@yb%
\pgfmathsincos@{\pgf@ya}%
\pgf@xb\pgfmathresultx\pgf@yc% ya is the back miter
\pgf@yb\pgfmathresulty\pgf@yc% yb is the top miter
\expandafter\expandafter\expandafter%
}\expandafter\expandafter\expandafter\pgf@xb\expandafter\the\expandafter\pgf@xb\expandafter\pgf@yb\the\pgf@yb%
% Inner length (pgfutil@tempdima) is now arrowlength - front miter - back miter
\pgfutil@tempdima\pgfarrowlength%
\advance\pgfutil@tempdima by-\pgf@xc%
\[email protected]\pgfarrowwidth%
\advance\pgfutil@tempdimb by\pgf@yb%
% Set back end
\ifpgfarrowroundjoin
\pgfarrowssetbackend{\pgf@ya\advance\pgf@x by-.5\pgfarrowlinewidth}
\else
\pgfarrowssetbackend{0pt}
\fi
% harpoon miter correction
\ifpgfarrowreversed
\pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by-\pgflinewidth\advance\pgf@x by\pgfarrowlinewidth}
\else
\pgfarrowssetlineend{\pgf@yc\advance\pgf@x by\pgflinewidth\advance\pgf@x by-\pgfarrowlinewidth}
\fi
\ifpgfarrowroundjoin
\pgfarrowssettipend{\pgfutil@tempdima\advance\pgf@x by.5\pgfarrowlinewidth}
\else
\pgfarrowssettipend{\pgfarrowlength\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi}
\fi
% The hull:
\pgfarrowshullpoint{\pgfarrowlength\ifpgfarrowroundjoin\else\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}%
\pgfarrowsupperhullpoint{\pgfarrowinset}{.5\pgfarrowwidth}%
\pgfarrowshullpoint{0pt}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}%
% Adjust the inset:
\advance\pgfarrowinset by\pgf@xb%
% The following are needed in the code:
\pgfarrowssavethe\pgfutil@tempdima
\pgfarrowssavethe\pgfutil@tempdimb
\pgfarrowssavethe\pgfarrowlinewidth
\pgfarrowssavethe\pgf@yc
\pgfarrowssavethe\pgfarrowinset
},
drawing code = {
\pgfsetdash{}{+0pt}
\ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi
\ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{\pgfarrowlinewidth}\fi
\pgfpathmoveto{\pgfqpoint{\pgf@yc}{0pt}}
\pgfpathlineto{\pgfqpoint{\pgfarrowinset}{\pgfutil@tempdimb}}
\pgfpathlineto{\pgfqpoint{\pgfutil@tempdima}{\pgfutil@tempdimb}}
\pgfpathlineto{\pgfqpoint{\pgfarrowinset}{0pt}}
\ifpgfarrowharpoon \else
\pgfpathlineto{\pgfqpoint{\pgfutil@tempdima}{-\pgfutil@tempdimb}}
\pgfpathlineto{\pgfqpoint{\pgfarrowinset}{-\pgfutil@tempdimb}}
\fi
\pgfpathclose
\ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi
},
parameters = {
\the\pgfarrowlinewidth,%
\the\pgfarrowlength,%
\the\pgfarrowwidth,%
\the\pgfarrowinset,%
\ifpgfarrowharpoon h\fi%
\ifpgfarrowopen o\fi%
\ifpgfarrowroundjoin j\fi%
},
}
\tikzset{
InvertedDiamond/.tip={InvertedKite[inset'=0pt 0.5]},
}
\begin{document}
\begin{tikzpicture}
\draw [help lines, step=0.5cm] grid (6,2);
\draw [ultra thick, {Diamond[open, length=2cm, line width=6pt]}-{InvertedDiamond[red, open, length=2cm, line width=6pt]}] (0,1) -- (6,1);
\end{tikzpicture}
\end{document}
箭头的尖端太靠前,仔细观察,箭头的顶部和底部可能距离边界辅助线远了半个点。
答案1
我能做的最好的事情是:
\documentclass[tikz]{standalone}
\usetikzlibrary{arrows.meta}
\pgfdeclarearrow{
name = InvertedKite,
defaults = {
length = +3.6pt +5.4,
width' = +0pt +0.5,
inset' = +0pt 0.25,
line width = +0pt 1 1,
},
setup code = {
% Cap the line width at 1/4th of the length
\[email protected]\pgfarrowlength
\ifdim\pgf@x<\pgfarrowlinewidth
\pgfarrowlinewidth\pgf@x
\fi
\[email protected]\pgfarrowwidth
\ifdim\pgf@x<\pgfarrowlinewidth
\pgfarrowlinewidth\pgf@x
\fi
% Compute front miter length:
\pgf@xa\pgfarrowlength%
\advance\pgf@xa by-\pgfarrowinset%
\pgfmathdivide@\pgf@xa\pgfarrowwidth%
\let\pgf@temp@quot\pgfmathresult%
\pgf@x\pgfmathresult pt%
\pgf@x\pgfmathresult\pgf@x%
\pgf@x4\pgf@x%
\advance\pgf@x by1pt%
\pgfmathsqrt@\pgf@x%
\pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter
\[email protected]\pgf@xc
\pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter
% Compute back miter length:
\pgfmathdivide@\pgfarrowinset\pgfarrowwidth%
\let\pgf@temp@quot\pgfmathresult%
\pgf@x\pgfmathresult pt%
\pgf@x\pgfmathresult\pgf@x%
\pgf@x4\pgf@x%
\advance\pgf@x by1pt%
\pgfmathsqrt@\pgf@x%
\pgf@yc\pgfmathresult\pgfarrowlinewidth% yc is back miter
\[email protected]\pgf@yc
\pgf@ya\pgf@temp@quot\pgfarrowlinewidth% ya is extra harpoon miter
% Compute top miter length:
{%
\[email protected]\pgfarrowwidth%
\pgfutil@tempdima\pgfarrowlength\advance\pgfutil@tempdima by-\pgfarrowinset%
\csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfutil@tempdima}{\pgfmath@tonumber\pgfutil@tempdimb}%
\pgf@yb\pgfmathresult pt%
\csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfarrowinset}{\pgfmath@tonumber\pgfutil@tempdimb}%
\pgf@ya\pgfmathresult pt%
\advance\pgf@yb by\pgf@ya%
\[email protected]\pgf@yb% half angle in yb
\ifdim\pgf@yb=45pt%
\def\pgfmathresult{1.414213}%
\else%
\pgfmathsin@{\pgf@yb}%
\pgfmathreciprocal@{\pgfmathresult}%
\fi%
\pgf@yc\pgfmathresult\pgfarrowlinewidth%
\[email protected]\pgf@yc%
\pgf@ya-\pgf@ya%
\advance\pgf@ya by-90pt%
\advance\pgf@ya by\pgf@yb%
\pgfmathsincos@{\pgf@ya}%
\pgf@xb\pgfmathresultx\pgf@yc% ya is the back miter
\pgf@yb\pgfmathresulty\pgf@yc% yb is the top miter
\expandafter\expandafter\expandafter%
}\expandafter\expandafter\expandafter\pgf@xb\expandafter\the\expandafter\pgf@xb\expandafter\pgf@yb\the\pgf@yb%
% Inner length (pgfutil@tempdima) is now arrowlength - front miter - back miter
\pgfutil@tempdima\pgfarrowlength%
\advance\pgfutil@tempdima by-\pgf@xc%
\advance\pgfutil@tempdima by-\pgfarrowlinewidth%
\[email protected]\pgfarrowwidth%
\advance\pgfutil@tempdimb by\pgf@yb%
% Set back end
\ifpgfarrowroundjoin
\pgfarrowssetbackend{\pgf@ya\advance\pgf@x by-.5\pgfarrowlinewidth}
\else
\pgfarrowssetbackend{0pt}
\fi
% harpoon miter correction
\ifpgfarrowreversed
\pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by-\pgflinewidth\advance\pgf@x by\pgfarrowlinewidth}
\else
\pgfarrowssetlineend{\pgf@yc\advance\pgf@x by\pgflinewidth\advance\pgf@x by-\pgfarrowlinewidth}
\fi
\ifpgfarrowroundjoin
\pgfarrowssettipend{\pgfutil@tempdima\advance\pgf@x by.5\pgfarrowlinewidth}
\else
\pgfarrowssettipend{\pgfarrowlength\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi}
\fi
% The hull:
\pgfarrowshullpoint{\pgfarrowlength\ifpgfarrowroundjoin\else\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}%
\pgfarrowsupperhullpoint{\pgfarrowinset}{.5\pgfarrowwidth}%
\pgfarrowshullpoint{0pt}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}%
% Adjust the inset:
\pgf@ya\pgfarrowinset%
\advance\pgfarrowinset by\pgf@xb%
\advance\pgfarrowinset by\pgf@xb%
%\advance\pgfarrowinset by\pgfarrowlinewidth%
% The following are needed in the code:
\pgfarrowssavethe\pgfutil@tempdima
\pgfarrowssavethe\pgfutil@tempdimb
\pgfarrowssavethe\pgfarrowlinewidth
\pgfarrowssavethe\pgf@yc
\pgfarrowssavethe\pgf@ya
\pgfarrowssavethe\pgfarrowinset
},
drawing code = {
\pgfsetdash{}{+0pt}
\ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi
\ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{\pgfarrowlinewidth}\fi
\pgfpathmoveto{\pgfqpoint{\pgf@yc}{0pt}}
\pgfpathlineto{\pgfqpoint{\pgfarrowinset}{\pgfutil@tempdimb}}
\pgfpathlineto{\pgfqpoint{\pgfutil@tempdima}{\pgfutil@tempdimb}} % too far
\pgfpathlineto{\pgfqpoint{\pgf@ya}{0pt}} % too close
\ifpgfarrowharpoon \else
\pgfpathlineto{\pgfqpoint{\pgfutil@tempdima}{-\pgfutil@tempdimb}}
\pgfpathlineto{\pgfqpoint{\pgfarrowinset}{-\pgfutil@tempdimb}}
\fi
\pgfpathclose
\ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi
},
parameters = {
\the\pgfarrowlinewidth,%
\the\pgfarrowlength,%
\the\pgfarrowwidth,%
\the\pgfarrowinset,%
\ifpgfarrowharpoon h\fi%
\ifpgfarrowopen o\fi%
\ifpgfarrowroundjoin j\fi%
},
}
\tikzset{
InvertedDiamond/.tip={InvertedKite[inset'=0pt 0.5]},
}
\begin{document}
\begin{tikzpicture}
\draw [help lines, step=0.5cm] grid (6,7);
\draw [ultra thick, {Diamond[open, length=2cm, line width=6pt]}-{InvertedDiamond[red, open, length=2cm, line width=6pt]}] (0,0.5) -- (6,0.5);
\draw [ultra thick, {Diamond[round, open, length=2cm, line width=6pt]}-{InvertedDiamond[round, red, open, length=2cm, line width=6pt]}] (0,2) -- (6,2);
\draw [ultra thick, {Diamond[open, length=2cm, line width=6pt]}-{InvertedDiamond[reversed, red, open, length=2cm, line width=6pt]}] (0,3.5) -- (6,3.5);
\draw [ultra thick, {Diamond[round, open, length=2cm, line width=6pt]}-{InvertedDiamond[reversed, round, red, open, length=2cm, line width=6pt]}] (0,5) -- (6,5);
\draw [ultra thick, {Diamond[open, length=2cm, line width=3pt]}-{InvertedDiamond[red, open, length=2cm, line width=3pt]}] (0,6.5) -- (6,6.5);
\end{tikzpicture}
\end{document}