倒钻石 TikZ 箭头

倒钻石 TikZ 箭头

我尝试根据 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}

在此处输入图片描述

相关内容