tikz:标签定位对于负缩放是否稳健?

tikz:标签定位对于负缩放是否稳健?

我有一个带节点的图,其中标签及其位置由外部控制。当使用一些负比例/x比例/y比例镜像图时,标签也应该改变其位置。这似乎排除了几种更强大的标签定位方法(镜像后标签不再位于正确的位置)。我快完成了,只剩下一个问题:标签的锚点位于中心。我需要的是一种自动将锚点设置为最靠近节点的点的方法。

\documentclass{standalone}
  \usepackage{tikz}
  \newcommand\mynode[2]%
    {\node[circle,draw,minimum width=1mm] (#2) at (#1) {};%
     \draw (#2) ++(\labelpos{#2}) node {\labelname{#2}};%
    }
  \newcommand\labelpos[1]{0.3,0} % dummy; really a lookup using #1 as key
  \newcommand\labelname[1]{xxx}  % dummy; really a lookup using #1 as key
\begin{document}
  \begin{tikzpicture}
  \mynode{0,0}{a}
  \mynode{1,1}{b}
  \end{tikzpicture}
\qquad
  \begin{tikzpicture}[scale=-1]
  \mynode{0,0}{a}
  \mynode{1,1}{b}
  \end{tikzpicture}
\end{document}

在此处输入图片描述 我想要的是: 在此处输入图片描述 请注意,一般来说,标签可能位于节点周围的任何位置,而不仅仅是左侧和右侧。

答案1

不幸的是,节点锚系统的设计几乎使这成为不可能。其精神是,尽管有各种变换,节点的定位都是相对于读者的观点

例如,在 中,node[anchor=north]{BAD}锚点位于字母“A”的顶点附近;在 中node[above right]{LOF},换句话说[anchor=south west],锚点位于字母“L”的角落附近。

还有一种粗暴的方法来转换节点。然而这不是你想要的。

\documentclass[border=9,tikz]{standalone}
\begin{document}
\tikz[transform shape,yscale=-2          ]\draw circle(.1)node[anchor=north]{BAD};
\tikz[transform shape,          rotate=60]\draw circle(.1)node[anchor=north]{BAD};
\tikz[transform shape,yscale=-2,rotate=60]\draw circle(.1)node[anchor=north]{BAD};
\end{document}

在实践中,你可以按照如下方式制定自己的定位选项:

  • 为了简单的目的,我们访问当前的转换矩阵并决定是否需要互相left替换。right

\makeatletter
\tikzset{
    relative  left/.code={\ifdim\pgf@pt@aa pt>0pt\tikzset{ left=#1}\else\tikzset{right=#1}\fi},
    relative right/.code={\ifdim\pgf@pt@aa pt<0pt\tikzset{ left=#1}\else\tikzset{right=#1}\fi},
    relative above/.code={\ifdim\pgf@pt@bb pt>0pt\tikzset{above=#1}\else\tikzset{below=#1}\fi},
    relative below/.code={\ifdim\pgf@pt@bb pt<0pt\tikzset{above=#1}\else\tikzset{below=#1}\fi}
}
\tikz\draw foreach\i in{1,...,9}{[rotate=\i*40](2,0)circle(.1)node[relative  left]{rel- left}};
\tikz\draw foreach\i in{1,...,9}{[rotate=\i*40](2,0)circle(.1)node[relative right]{rel-right}};
\tikz\draw foreach\i in{1,...,9}{[rotate=\i*40](0,2)circle(.1)node[relative above]{rel-above}};
\tikz\draw foreach\i in{1,...,9}{[rotate=\i*40](0,2)circle(.1)node[relative below]{rel-below}};
  • 如果想要输入角度并相应地获得离散锚点,我们可以借用一些宏[auto]

\tikzset{
    discrete anchor by angle/.code={
        \pgfpointtransformed{\pgfpointpolar{#1+90}{1pt}}
        \tikz@auto@anchor
    }
}
\tikz\draw foreach\i in{1,..., 8}{[rotate=\i*45](1,1)circle(.1)node[discrete anchor by angle=225]{discr-ang}};
\tikz\draw foreach\i in{1,...,90}{[rotate=\i* 4](1,1)circle(.1)node[discrete anchor by angle=225]{discr-ang}};
  • 如果想要获得连续输出,我们可以按照评论链接中的@Qrrbrbirlbel 的回答

\tikzset{
    continuous anchor by angle/.code={
        \pgfpointtransformed{\pgfpointpolar{#1}{1pt}}
        \pgfmathanglebetweenpoints{\pgfqpoint{-\pgf@x}{-\pgf@y}}{\pgfpointorigin}
        \def\tikz@anchor{\pgfmathresult}
    }
}
\tikz\draw foreach\i in{1,..., 8}{[rotate=\i*45](1,1)circle(.1)node[continuous anchor by angle=225]{conti-ang}};
\tikz\draw foreach\i in{1,...,90}{[rotate=\i* 4](1,1)circle(.1)node[continuous anchor by angle=225]{conti-ang}};
  • 有人可能想输入离散键

\tikzset{
    discrete anchor by key/.code={
        \csname tikz@label@angle@is@#1\endcsname
        \tikzset{discrete anchor by angle=\tikz@label@angle+180}
    }
}
\tikz\draw foreach\i in{1,..., 8}{[rotate=\i*45](1,1)circle(.1)node[discrete anchor by key=above right]{discr-key}};
\tikz\draw foreach\i in{1,...,90}{[rotate=\i* 4](1,1)circle(.1)node[discrete anchor by key=above right]{discr-key}};

相关内容