自定义 tikz 形状: \pgfdeclareshape 的高级替代方案

自定义 tikz 形状: \pgfdeclareshape 的高级替代方案

所以我一直在研究如何在 TikZ 中制作自己的形状。正如我所了解的 LaTeX 中的大多数东西一样,它似乎有一个非常深的兔子洞。

所以我想知道——有没有简单的出路?

是否可以定义一个可以在“两个坐标之间”使用的新​​形状(即\draw (A) open box (B)),例如\path\draw,在定义时使用熟悉的符号?

例如,可以做这样的事情;作为一个最小的例子,我制作一个没有顶部的矩形:

\documentclass[border=10mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,fit}
\tikzset{
  % When open box is called via edge, draw a rectangle with no top:
  open box/.code={%
      \pgfkeysalso{%
        to path={%
            let
            \p{start}=(\tikztostart),
            \p{end}=(\tikztotarget)
            in
            (\tikztostart) -| (\tikztotarget)
            (\x{start},\y{start}) -- (\x{start},\y{end})
            % Make a fitted node to get good anchors
            node[fit={(\tikztostart)(\tikztotarget)}, inner sep=0pt](#1){}
          }
      }
    }
}

\begin{document}
  \begin{tikzpicture}
    \draw (0,0) edge[open box={therect}] (2,2);
    % How can this be switched with e.g:            %<---
    % \draw (0,0) open box[name=therect] (2,2) %<---
    \node at (therect.center){RECT!};
  \end{tikzpicture}
\end{document}

结果是:

实际上,我并不认为这种语法很糟糕,但我想知道是否有更简单的东西可以用于这种事情,但我只是还没有偶然发现?

谢谢! :)

答案1

我不知道如何在不改变 Ti 的情况下实现你建议的语法Z 解析器。后者可以实现,但需要付出很大努力。给出了明确的例子,例如在 Jake 的帖子中在 Loopspace 的帖子中然而后者也包含着一段非常明确的说法:

我仍然强烈推荐路径解决方案。除非您知道自己在做什么,否则不要破坏 TikZ 代码。

我确实同意这句话中表达的观点。因此,我只建议缩短您的代码(不需要calc,也不需要\pgfkeysalso,这里绘制路径的方式使角落看起来不错,节点文本可以作为第二个参数)。

\documentclass[border=10mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{fit}
\tikzset{
  % When open box is called via edge, draw a rectangle with no top:
  open box/.style 2 args={%
        to path={%
            (\tikztostart|-\tikztotarget) -- (\tikztostart) -| (\tikztotarget)
            node[fit={(\tikztostart)(\tikztotarget)}, inner sep=0pt](#1){#2}
          }
    }
}

\begin{document}
  \begin{tikzpicture}
    \draw (0,0) to[open box={therect}{RECT!}] (2,2);
  \end{tikzpicture}
\end{document}

在此处输入图片描述

你也可以让它更 TiZy 使用 pgf 键而不是具有多个选项的样式。

\documentclass[border=10mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{fit}
\tikzset{
  % When open box is called via edge, draw a rectangle with no top:
  open box/.style={%
        /utils/exec=\tikzset{/tikz/obox/.cd,#1},
        to path={%
            (\tikztostart|-\tikztotarget) -- (\tikztostart) -| (\tikztotarget)
            node[fit={(\tikztostart)(\tikztotarget)},obox/style]
        (\pgfkeysvalueof{/tikz/obox/name})
        {\pgfkeysvalueof{/tikz/obox/contents}}
          }
    },obox/.cd,name/.initial={},contents/.initial={},style/.style={inner sep=0pt}
}

\begin{document}
  \begin{tikzpicture}
    \draw (0,0) to[open box={name=rect,contents={RECT!}}] (2,2);
  \end{tikzpicture}
\end{document}

如果目的只是创建这种类型的节点形状,你可以这样做

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{shapes.geometric}
\begin{document}
\begin{tikzpicture}[open box/.style={regular polygon,regular polygon sides=4,
name=opbo,append after command={(opbo.north west)|-(opbo.south east)--(opbo.north east)}}]
\draw node[open box]{RECT!};
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容