Acesse a opção de escala no ambiente TikZ

Acesse a opção de escala no ambiente TikZ

Ao usar a opção de escala no \tikz[xscale=2]etc, existe alguma maneira de acessar a configuração de escala no ambiente TikZ?

Responder1

Como diz Andrew, você pode usar a matriz de transformação, que é um acúmulo de todas as transformações aplicadas atualmente ao escopo atual. Os detalhes relevantes são encontrados nas Seções 104.2.1 e 104.2.4 doManual PGF(v3.0.0).

Eu defini um comando \getmytransformmatrixque armazena a representação interna da matriz de transformação do PGF nas macros \mya, \myb, \myc, \myd, \myse \myt. Estes correspondem à transformação de coordenadas (x,y) --> (a*x + b*y + s, c*x + d*y +t). Portanto, o acumulado xscalee yscale(base CS global) são armazenados em \myae \myd, respectivamente. Da mesma forma, as dimensões xshifte yshiftsão armazenadas em \myse \myt, respectivamente.

Eles não são persistentes entre limites/níveis de escopo, portanto, o comando \getmytransformmatrixdeve aparecer em todos os escopos nos quais você deseja usar as informações.

O Código (com breve ilustração)

\documentclass{standalone}
\usepackage{tikz}

\newcommand\getmytransformmatrix{%
  \pgfgettransformentries{\mya}{\myb}{\myc}{\myd}{\mys}{\myt}%
% coordinate (x,y) is transformed to (ax + by + s, cx + dy + t)  
}

\newcommand\drawmyaxes[1][]{% just for convenience
  \draw (0,0) -- ++(1,0) node[right] {$x#1$};
  \draw (0,0) -- ++(0,1) node[above] {$y#1$};
}

\newcommand\myvar[2]{\texttt{#1~=~#2}} % just for convenience

\begin{document}
\begin{tikzpicture}[xshift=2pt]
  \getmytransformmatrix
  \drawmyaxes
  \node[align=left] at (-5,0) {Outside the scope, we have\\ 
    \myvar{xscale}{\mya}, \myvar{yscale}{\myd}.};
  \begin{scope}[yshift=-5pt,rotate=45]
    \getmytransformmatrix
    \drawmyaxes[']
    \node[align=left] at (-1,-1) {Inside the scope, we have\\ 
      \myvar{xscale}{\mya}, \myvar{yscale}{\myd}.\\
      We also see that \myvar{xshift}{\mys}\\
      and \myvar{yshift}{\myt}.};
  \end{scope}
  \node[align=left] at (5,0) {Outside the scope again, we have\\
    \myvar{xscale}{\mya}, \myvar{yscale}{\myd}.};
\end{tikzpicture}
\end{document}

A saída

insira a descrição da imagem aqui

Observe que a matriz não é “lembrada” fora do escopo, e que isso mostra a transformação acumulada ( xshift=2ptdo ambiente originale yshift=-5ptdo escopo).

As variáveis ​​adicionais bpodem cser utilizadas para outros cálculos; por exemplo, para calcular a rotação efetiva ( atan(\myd/\mya)funcionaria apenas a partir de (-90,90) ).

Responder2

A resposta para isso depende de qual é o seu propósito ao salvar o arquivo xscale. Existem duas possibilidades em que posso pensar:

  1. Você quer saber o que foi passado via xscale.
  2. Você quer saber xscaleo escopo atual.

O primeiro é bastante fácil, o segundo depende do que você entende por xscale.

A razão pela qual o primeiro não é trivial é porque o TikZ não se preocupa em salvar o valor que você passa, ele simplesmente o aplica e depois esquece. Portanto, você precisa adicionar um wrapper ao redor da xscalechave que salva o valor para uso posterior. Aqui está um código para isso:

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

\tikzset{
  saved xscale/.initial=1,
  save xscale/.style={
    xscale=#1,
    save the xscale=#1
  },
  save the xscale/.code={%
    \pgfmathparse{#1 * \pgfkeysvalueof{/tikz/saved xscale}}%
    \pgfkeysalso{saved xscale/.expand once=\pgfmathresult}%
  }
}

\begin{document}
\begin{tikzpicture}
\begin{scope}[save xscale=2]
\node at (0,0) {\pgfkeysvalueof{/tikz/saved xscale}};
\begin{scope}[save xscale=2]
\node at (1,0) {\pgfkeysvalueof{/tikz/saved xscale}};
\end{scope}
\end{scope}
\node at (2,0) {\pgfkeysvalueof{/tikz/saved xscale}};
\end{tikzpicture}
\end{document}

(Esta pode não ser a maneira mais elegante de conseguir isso.)

As dificuldades com o segundo são porque o TikZ pode aplicarqualquertransformação afim a partes de um desenho. Então você tem que encontrar um significado para xscaleuma transformação afim arbitrária. Considere os dois cenários a seguir:

  1. Você aplica xscale=2e depois aplica uma rotação de π/2 (sentido anti-horário). A matriz resultante é

    [0 -1]
    [2  0]
    
  2. Você aplica a rotação primeiro e depois faz yscale=2. A matriz resultante é

    [0 -1]
    [2  0]
    

Portanto, essas duas operações levam à mesma matriz. Essa matriz é xscaleigual 2ou yscaleigual a 2? Ou são ambos 0?

Agora considere fazer a rotação e então xscale=2. Isso produz:

[0 -2]
[1  0]

Então, para todos esses cenários, você tem que decidir o que xscaledeveria ser. Existem definições razoáveis, mas exatamente o que dependerá do que você deseja fazer com elas.

Assim, o melhor que você pode fazer é examinar a matrizcomo um todoe calcule algum número que funcione para tudo o que você deseja fazer, mas como isso não está especificado na pergunta, não é viável responder a isso.

Para obter as entradas da própria matriz (bem, a matriz e a tradução), você pode usar o comando PGF \pgfgettransformentries. Então faça o que quiser com eles. Por exemplo, se você quiser saber ogeralescala, você poderia tirar a raiz quadrada do valor absoluto de seu determinante. Se você quiser saber o comprimento do vetor que (1,0)eventualmente se torna, você pode calculá-lo.

Resumindo:

  1. Para armazenar os valores acumulados passados ​​para xscale, basta armazená-los antes de passá-los,
  2. Para extrair xscaleda matriz de transformação, use os comandos PGF para acessar a matriz, descubra o que você quer dizer com xscalematriz arbitrária e, em seguida, calcule-a a partir dos valores recuperados.

informação relacionada