我正在尝试在形状边缘等距创建多个锚点。我尝试的方法是在节点中传递一个键值,然后该键值将定义锚点。
以下代码试图通过在主 pgfdeclareshape 部分中使用循环来实现这一点。尽管循环有效并创建了一个锚点(目前处于错误的位置),但它只会创建一个锚点,因为键仍然具有初始值。
\documentclass[a4paper]{article}
\usepackage{tikz}
\makeatletter
\tikzset{anchorpoints/.initial = 1}
\pgfdeclareshape{hat}{
\inheritsavedanchors[from=rectangle]
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{north}
% This loop will go through once for each anchorpoints and create an anchor
\c@pgf@counta=0
\pgfkeysgetvalue{/tikz/anchorpoints}{\anchorpoints}
\c@pgf@countb\anchorpoints\relax
\pgfmathloop
\ifnum\c@pgf@counta<\c@pgf@countb\relax
\pgfmathtruncatemacro{\anchorname}{\c@pgf@counta}\relax
\xdef\doanchor{
\noexpand\anchor{o\anchorname}{
\noexpand\northeast
\noexpand\pgf@y=1\noexpand\pgf@y%
}
}\doanchor
\advance\c@pgf@counta 1\relax
\repeatpgfmathloop
\backgroundpath{
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgfmathsetlength{\pgf@xc}{\pgf@xa + (\pgf@xb - \pgf@xa)/2}
\pgfpathmoveto{\pgfpoint{\pgf@xc}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
\pgfpathclose
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node [shape=hat,draw=black,scale=0.75,anchorpoints=3] (1) at (0, 0) {};
\end{tikzpicture}
\end{document}
有没有办法等到设置完密钥后再创建锚点?如果我尝试将一些 .code 放入密钥中,那么它将在更改时执行,但似乎此时创建锚点已经太晚了。
答案1
这是在库regular polygon
中的形状中完成的shapes.geometric
。在声明形状之前,边数是未知的,但锚点应在形状定义中声明。声明通过添加代码在调用时声明额外的锚点来绕过此限制。
当使用节点形状时,会调用某个宏来设置大量内容(保存的宏、保存的锚点、路径等)。宏的各个部分都会\pgfdeclarefunction
向其中添加代码,但它们以特定的方式添加。声明的作用regular polygon
是向此宏添加一些额外的代码。这些额外的代码设置了必要的额外锚点。在形状声明中,它是以以下内容开始的部分:
\expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@regular polygon\endcsname{%
然后实际代码会添加必要的锚点定义。它会循环遍历边数,如果锚点定义尚未存在,则添加锚点定义。代码看起来有点糟糕,但那只是因为\noexpand
中 s的数量非常多\xdef
。
一个重要的副作用是,这些额外的锚点随后可供所有后续regular polygon
s 使用,无论其边数是多少。因此,如果您绘制了一个七边形,然后又绘制了一个五边形,您仍然可以引用五边形上边 6 和 7 上的锚点。
我在自己的作品中使用了这种技术量子场论我从该regular polygon
代码改编的包。