
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 \getmytransformmatrix
que armazena a representação interna da matriz de transformação do PGF nas macros \mya
, \myb
, \myc
, \myd
, \mys
e \myt
. Estes correspondem à transformação de coordenadas (x,y) --> (a*x + b*y + s, c*x + d*y +t)
. Portanto, o acumulado xscale
e yscale
(base CS global) são armazenados em \mya
e \myd
, respectivamente. Da mesma forma, as dimensões xshift
e yshift
são armazenadas em \mys
e \myt
, respectivamente.
Eles não são persistentes entre limites/níveis de escopo, portanto, o comando \getmytransformmatrix
deve 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
Observe que a matriz não é “lembrada” fora do escopo, e que isso mostra a transformação acumulada ( xshift=2pt
do ambiente originale yshift=-5pt
do escopo).
As variáveis adicionais b
podem c
ser 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:
- Você quer saber o que foi passado via
xscale
. - Você quer saber
xscale
o 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 xscale
chave 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 xscale
uma transformação afim arbitrária. Considere os dois cenários a seguir:
Você aplica
xscale=2
e depois aplica uma rotação de π/2 (sentido anti-horário). A matriz resultante é[0 -1] [2 0]
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 é xscale
igual 2
ou yscale
igual 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 xscale
deveria 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:
- Para armazenar os valores acumulados passados para
xscale
, basta armazená-los antes de passá-los, - Para extrair
xscale
da matriz de transformação, use os comandos PGF para acessar a matriz, descubra o que você quer dizer comxscale
matriz arbitrária e, em seguida, calcule-a a partir dos valores recuperados.