在 TikZ 中变换定义的坐标

在 TikZ 中变换定义的坐标

假设我有一个三角形,其顶点定义如下

\coordinate (a) at (0,0);
\coordinate (b) at (1,0);
\coordinate (c) at (0,1);

让我们用 表示由和T(x,y)定义的三角形,该三角形由向量 平移。我现在可以轻松绘制如下图所示:(a),(b)(c)(x,y)T(0,0)

\draw (a) -- (b) -- (c) -- cycle;

到目前为止一切顺利。现在,假设我想绘制三角形T(2,3)。理想情况下,我想做类似的事情:

\begin{scope}[shift={(2,3)}]
    \draw (a) -- (b) -- (c) -- cycle;
\end{scope}

然而,由于坐标是在范围之外定义的,因此变换(在本例中为平移)不会影响它们。参见这个答案。什么是明智的做法?或者更一般地说:

重新使用在不同变换下定义一次的坐标的最佳方法是什么?

可能的解决方案:根据@Qrrbrbirlbel 的评论,我发布了一个答案。然而,这个答案非常有限且具有局部性 - 是否有更通用的东西?

答案1

在 TikZ/pgf 中,变换仅适用于数字坐标。要从nodes 或coordinates 检索原始数字坐标,可以使用以下let操作:

在此处输入图片描述

\documentclass[tikz]{standalone}
\usetikzlibrary{calc,scopes}
\begin{document}
\begin{tikzpicture}
  \coordinate (a) at (0,0);
  \coordinate (b) at (1,0);
  \coordinate (c) at (0,1);
  \draw (a) -- (b) -- (c) -- cycle;

  \draw[blue] let \p{a}=(a),\p{b}=(b),\p{c}=(c) in
  {[rotate=30] (\p{a}) -- (\p{b}) -- (\p{c}) -- cycle}
  {[shift={(2,3)}] (\p{a}) -- (\p{b}) -- (\p{c}) -- cycle};
\end{tikzpicture}
\end{document}

答案2

由于链接中的其他问题已经解释了这个问题,我就不再重复老问题了。查看代码,似乎没有一种简单的方法可以说“将以下样式(例如,shift={(2,3)})应用于以下所有点。”。没有every point样式(对比许多every pathevery node或......)。此外,添加一个并不简单,因为坐标解析器需要查看才能[调用执行转换的位(此处的代码uhoh... options!在这一点上有启发性的注释)。

所以没有真的真的简单的解决方案。但是有一种方法可以使用样式使正确的方法更简单一些。

\documentclass{article}
%\url{http://tex.stackexchange.com/q/98924/86}
\usepackage{tikz}

\tikzset{
  c/.style={every coordinate/.try}
}

\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0,0);
\coordinate (B) at (1,0);
\coordinate (C) at (0,1);
\draw (A) -- (B) -- (C) -- cycle;
\begin{scope}[every coordinate/.style={shift={(2,3)}}]
    \draw ([c]A) -- ([c]B) -- ([c]C) -- cycle;
\end{scope}
\end{tikzpicture}
\end{document}

移位三角形

显然,样式名称c可以用其他名称替换,以避免与其他名称(例如坐标名称)混淆。选择单个字母的理由是每次输入时都相对容易,并且该字母c是“坐标”的缩写。

答案3

添加通用样式并不是一件简单的事情every coordinate。但是,\iftikztransformnodecoordinates破解却相当简单。

\documentclass{standalone}
\usepackage{tikz}

\makeatletter
\newif\iftikztransformnodecoordinates
\tikzset{transform node coordinates/.is if=tikztransformnodecoordinates}


\def\tikz@parse@node#1(#2){%
    \pgfutil@in@.{#2}%
    \ifpgfutil@in@
        \tikz@calc@anchor#2\tikz@stop%
    \else%
        \tikz@calc@anchor#2.center\tikz@stop%
        \expandafter\ifx\csname pgf@sh@ns@#2\endcsname\tikz@coordinate@text%
        \else
            \tikz@shapebordertrue%
            \def\tikz@shapeborder@name{#2}%
        \fi%
    \fi%
    \iftikztransformnodecoordinates%
        \pgf@pos@transform{\pgf@x}{\pgf@y}%
    \fi
    \edef\tikz@marshal{\noexpand#1{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}%
    \tikz@marshal%
}

\begin{document}

\begin{tikzpicture}

\coordinate (a) at (0,0);
\coordinate (b) at (1,0);
\coordinate (c) at (0,1);

\draw (a) -- (b) -- (c) -- cycle;

\draw [red, transform node coordinates, rotate=10] 
    (a) -- (b) -- (c) -- cycle;

\draw [green, transform node coordinates, shift={(1,1)}] 
    (a) -- (b) -- (c) -- cycle;

\draw [blue, transform node coordinates, rotate=10, shift={(1,1)}] 
    (a) -- (b) -- (c) -- cycle;

\end{tikzpicture}

\end{document}

节点坐标变换

但不确定它是否 100% 坚固。

答案4

r那么定义一个应用转换的通用锚点(相对锚点)怎么样?编辑:现在是一个真正有效的版本!

两个问题:

  • 调用通用锚点的代码需要节点 cs 中的坐标。
  • 相同的代码应用外部变换的逆变换 --- 这就是使命名坐标绝对的原因!

我们的工作是执行所有这些操作的逆操作(按相反的顺序)。

\documentclass{article}
\usepackage{tikz}

\makeatletter
\pgfdeclaregenericanchor{r}{%
  % 1. get (x,y) in the node's cs
  \pgf@sh@reanchor{\csname pgf@sh@ns@\pgfreferencednodename\endcsname}{center}%
  {% 2. apply the node transformation
    \pgfsettransform{\csname pgf@sh@nt@\pgfreferencednodename\endcsname}%
    \pgf@pos@transform{\pgf@x}{\pgf@y}%
    \global\pgf@x=\pgf@x%
    \global\pgf@y=\pgf@y%
  }%
  % 3. *don't* apply the inverse of the outer transformation! We want
  %    relative coordinates!
  {% 4. apply the inverse of the inverse of the outer transform
   %    (cancels the inverse of the outer transformation done by \pgfpointanchor)
    \pgf@pos@transform{\pgf@x}{\pgf@y}%
    \global\pgf@x=\pgf@x%
    \global\pgf@y=\pgf@y%
  }%
  {% 5. apply the inverse of the nodes transformation (cancels the node
   %    transformation done by \pgfpointanchor)
    \pgfsettransform{\csname pgf@sh@nt@\pgfreferencednodename\endcsname}%
    \pgftransforminvert
    \pgf@pos@transform{\pgf@x}{\pgf@y}%
    \global\pgf@x=\pgf@x%
    \global\pgf@y=\pgf@y%
  }%
}
\makeatother

\begin{document}

\begin{tikzpicture}
  \coordinate (a) at (0,0);
  \coordinate (b) at (1,0);
  \coordinate (c) at (0,1);
  \draw[blue,ultra thick] (a) -- (b) -- (c) -- cycle;
  \begin{scope}[shift={(2,0)},scale=2]
    \draw[red] (a.r) -- (b.r) -- (c.r) -- cycle;
  \end{scope}
\end{tikzpicture}

\end{document}

缩放和平移的三角形

相关内容