自定义节点形状中忽略装饰标记箭头样式吗?

自定义节点形状中忽略装饰标记箭头样式吗?

我有这个尺寸线宏,它是根据这里的例子整理出来的;它应该可以从 MWE(下面)输出中看到:

测试05a

\draw...当从(A)中的“常规”调用时,它工作得很好{tikzpicture}- 但是,当它\draw是对自定义节点形状的调用的一部分时\pgfdeclareshape{myshape}{...时- 那么箭头的旋转和缩放选项都是被忽略,当绘制尺寸线(M)时?!(编辑:我也尝试了颜色参数;奇怪的是,那个是不是被忽略了??)

为什么会发生这种情况?以及如何让这条箭头线在自定义形状中也能工作,就像在正常情况下一样?

妇女权利委员会:

\documentclass[varwidth,tightpage,border=1bp]{standalone}

\usepackage{tikz}
\usetikzlibrary{decorations}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{shapes}
\usetikzlibrary{calc}

\pagecolor{yellow!15} % ignored with preview, but not w/ varwidth

\begin{document}

Hello:

\begin{tikzpicture}

\tikzset{
  %instead of dimen/.style={, using tconarrC for dimen!
  declare function={multip(\a,\b)=\a*\b;}, % otherwise cannot use pgfmathparse here
  tconarrC/.style n args={5}{
    line width=#3,
    draw=#5,
    decoration={markings,
      mark=at position 0 with {\arrow[rotate=180,scale=#4,fill=#5]{#1}}, 
      mark=at position 1 with {\arrow[scale=#4,fill=#5]{#2}}, 
    },
    shorten >={multip(#4,#3)},
    shorten <={multip(#4,#3)},
    postaction={decorate},
  },
  tconarrC/.default={latex}{latex}{3pt}{1.3}{black},
  dimen/.style={|-|,
    tconarrC={latex}{latex}{\pgflinewidth}{2.0}{black},
    every rectangle node/.style={midway,},
  },
  minbox/.style={shape=rectangle,inner sep=0pt,outer sep=0pt,minimum size=0pt},
} % end tikzset
\makeatletter
\pgfdeclareshape{myshape}{ %
  \inheritsavedanchors[from={rectangle}] %
  \inheritbackgroundpath[from={rectangle}] %
  \inheritanchorborder[from={rectangle}] %
  \foreach \x in {center,north,north east,north west,south,south east,south west,east,west}{ %
    \inheritanchor[from={rectangle}]{\x} %
  } %
  \backgroundpath{ %
    \edef\ename{\tikz@fig@name} %
    \node[rectangle,minimum size=10pt,draw] (\ename-A) at (\ename.east) {};
    \node[rectangle,minimum size=10pt,draw] (\ename-B) at (\ename.west) {};
  }
  \foregroundpath{ %
    % here, minbox must have a shape (e.g. rectangle) defined!
    % else ! TeX capacity exceeded, sorry [grouping levels=255].
    \draw[dimen] (\ename-A.center) -- (\ename-B.center)
      node[minbox,above=0pt] (\ename-L) {M}
    ;
  }
}

\node[fill] (origin) at (0,0) {};

\node[myshape,minimum size=2cm,anchor=south west] (tshape) at (1,1) {};

\draw[dimen] ($(tshape-A)-(0,2em)$) -- ($(tshape-B)-(0,2em)$) node[above=0pt] {A};

\end{tikzpicture}
\end{document}

答案1

好的,我想我找到了某种解决方法 - 看起来不错(除了尺寸线端点似乎不是确切地在节点中心处):

测试05b.png

\pgf*... 通过尝试在代码中随机地以蛮力方式加入我在手册中找到的与坐标系转换相关的任何命令,然后查看它们的效果(参见下面 MWE 中的注释)

诀窍本质上是这样做:

decoration={markings,
  mark=at position 0 with {%
    \pgftransformresetnontranslations %
    \pgftransformscale{#4} % 
    \arrow[sloped,rotate=0,scale=1,fill=#5]{#1}; %
  },
  mark=at position 1 with {% 
    %\pgftransformresetnontranslations  % NOT HERE!
    \pgftransformscale{#4} % 
    \arrow[sloped,scale=1,fill=#5]{#2};
  },
},

为什么?我不知道——我不知道;尤其因为如果我在代码中打印出这些点的变换矩阵,它们就是确切地相同的(缩放部分,而不是平移部分),无论它们从哪里调用;下面的 MWE 打印出来:

pos 0: pgfgettransform: {-1.0}{0.0}{0.0}{-1.0}{90.95824pt}{62.30548pt}; pgf@pt@
aa, pgf@pt@ba, pgf@pt@ab, pgf@pt@bb: -1.0, 0.0, 0.0, -1.0
pos 1: pgfgettransform: {-1.0}{0.0}{0.0}{-1.0}{33.65276pt}{62.30548pt}; pgf@pt@
aa, pgf@pt@ba, pgf@pt@ab, pgf@pt@bb: -1.0, 0.0, 0.0, -1.0
pos 0: pgfgettransform: {-1.0}{0.0}{0.0}{-1.0}{90.95824pt}{42.30545pt}; pgf@pt@
aa, pgf@pt@ba, pgf@pt@ab, pgf@pt@bb: -1.0, 0.0, 0.0, -1.0
pos 1: pgfgettransform: {-1.0}{0.0}{0.0}{-1.0}{33.65276pt}{42.30545pt}; pgf@pt@
aa, pgf@pt@ba, pgf@pt@ab, pgf@pt@bb: -1.0, 0.0, 0.0, -1.0

好吧,希望有人最终能正确地澄清这一点 - 与此同时,我希望这是尺寸箭头问题。

妇女权利委员会:

\documentclass[varwidth,tightpage,border=1bp]{standalone}

\usepackage{tikz}
\usetikzlibrary{decorations}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{shapes}
\usetikzlibrary{calc}

\pagecolor{yellow!15} % ignored with preview, but not w/ varwidth

\begin{document}

Hello:

\begin{tikzpicture}

\makeatletter
% http://tex.stackexchange.com/questions/185444/
\gdef\tout{}\gdef\trfm{}
\gdef\typeoutMyInfoString#1{%
  \pgfgettransform{\trfm}%
  \edef\tout{#1 %
    pgfgettransform: \trfm ; %
    pgf@pt@aa, pgf@pt@ba, pgf@pt@ab, pgf@pt@bb: \pgf@pt@aa, \pgf@pt@ba, \pgf@pt@ab, \pgf@pt@bb %
  }
  \typeout{\tout} %
}
\makeatother

\gdef\myset{
\tikzset{ %
  %instead of dimen/.style={, using tconarrC for dimen!
  declare function={multip(\a,\b)=\a*\b;}, % otherwise cannot use pgfmathparse here
  tconarrC/.style n args={5}{
    line width=##3,
    draw=##5,
    decoration={markings,
      mark=at position 0 with {%
        \typeoutMyInfoString{pos 0:}%
        % (c0)
        \pgftransformresetnontranslations %
        % (c1)
        \pgftransformscale{##4} % this works the same for both;
                                % so don't scale the arrow
        \arrow[sloped,rotate=0,scale=1,fill=##5]{##1}; % (c3)
      },
      mark=at position 1 with {% 0.999999
        % here we seemingly have correct orientation between M and A;
        % just the scale is different; so only scale needed.
        \typeoutMyInfoString{pos 1:}%
        %\pgftransformresetnontranslations  % causes both arrows to
                                            % rotate/orient wrongly!
                                            % without it, all is correct
        \pgftransformscale{##4} % this works the same for both;
                                % so don't scale the arrow
        \arrow[sloped,scale=1,fill=##5]{##2};
      },
    },
    shorten >={multip(##4,##3)},
    shorten <={multip(##4,##3)},
    reset transform/.code={},%\pgftransformreset}, %is called anyway
    %decorate, % cannot, no line is drawn
    %preaction={reset transform,decorate}, % meh
    postaction={reset transform,decorate},
  },
  tconarrC/.default={latex}{latex}{3pt}{1.3}{black},
  dimen/.style={|-|,
    tconarrC={latex}{latex}{\pgflinewidth}{2.0}{gray},
    every rectangle node/.style={midway,},
  },
  minbox/.style={shape=rectangle,inner sep=0pt,outer sep=0pt,minimum size=0pt},
} % end tikzset
} % end gdef
\myset % execute
\makeatletter
\pgfdeclareshape{myshape}{ %
  \inheritsavedanchors[from={rectangle}] %
  \inheritbackgroundpath[from={rectangle}] %
  \inheritanchorborder[from={rectangle}] %
  \foreach \x in {center,north,north east,north west,south,south east,south west,east,west}{ %
    \inheritanchor[from={rectangle}]{\x} %
  } %
  %\myset % ! Package pgfkeys Error: I do not know the key '/tikz/dimen'
  \backgroundpath{ %
    \edef\ename{\tikz@fig@name} %
    \node[rectangle,minimum size=10pt,draw] (\ename-A) at (\ename.east) {};
    \node[rectangle,minimum size=10pt,draw] (\ename-B) at (\ename.west) {};
  }
  \foregroundpath{ %
    %\myset % ! Package pgfkeys Error: I do not know the key '/tikz/dimen'
    % here, minbox must have a shape (e.g. rectangle) defined!
    % else ! TeX capacity exceeded, sorry [grouping levels=255].
    \draw[dimen] (\ename-A.center) -- (\ename-B.center)
      node[minbox,above=0pt] (\ename-L) {M}
    ;
  }
} % declareshape
\makeatother

\node[fill] (origin) at (0,0) {};

\node[myshape,minimum size=2cm,anchor=south west] (tshape) at (1,1) {};

\draw[dimen]
  ($(tshape-A.center)-(0,2em)$) -- ($(tshape-B.center)-(0,2em)$)
  node[above=0pt] {A};

\end{tikzpicture}
\end{document}


        % (c0)
%         \pgfgettransformentries{\ta}{\tb}{\tc}{\td}{\tx}{\ty} %
%         \pgfusepath{draw,stroke} %
%         \pgfinterruptpath % nothing
        %\tikz\draw[-latex](\tx,\ty) ; % completely messes up sizing
%         \draw[-latex](0pt,0pt) ; % sizing presserved; \tx,\ty moves to bottom left corner; 0,0 is relative; arrows points "up" like this, unscaled! ,rotate=90 is ignored
%         \node[draw=none,rotate=180,inner sep=0pt] (ti) {\tikz\draw[-latex](0pt,0pt);}; % somewhat messed up; same at at (0pt,0pt); M leaks?

        % (c1)
%         \node[rotate=-90,inner sep=0pt,outer sep=0pt,minimum size=0pt,anchor=west] (ti) {\tikz\draw[-latex](0pt,0pt);}; % rotate works here, but opposite directions A and M? with \pgftransformresetnontranslations they finally orient the same!
%         \node[draw=none,rotate=180,inner sep=0pt,anchor=center] (ti) {\tikz\arrow{latex};}; % somewhat messed up
%         \draw[-latex,rotate=180](0pt,0pt); % same rotation, but rotate ignored!

        % (c3)
% with rotate=180, A is correct, M ignores;  with rotate=0, A only rotates, M stays same (bad) ; with \pgftransformresetnontranslations and rotate=0, finally both arrows point the same way correctly
%         \endpgfinterruptpath %

相关内容