
При использовании опции масштабирования в \tikz[xscale=2]
etc, есть ли способ получить доступ к настройке масштаба из среды TikZ?
решение1
Как говорит Эндрю, вы можете использовать матрицу преобразования, которая является аккумулированием всех преобразований, которые в настоящее время применяются к текущей области. Соответствующие детали можно найти в разделах 104.2.1 и 104.2.4Руководство ПГФ(v3.0.0).
Я определил команду \getmytransformmatrix
, которая сохраняет внутреннее представление матрицы преобразования PGF в макросы \mya
, \myb
, \myc
, \myd
, \mys
, и \myt
. Они соответствуют преобразованию координат (x,y) --> (a*x + b*y + s, c*x + d*y +t)
. Таким образом, накопленные xscale
и yscale
(глобальный базис CS) хранятся в \mya
и \myd
, соответственно. Аналогично, измерения xshift
и yshift
хранятся в \mys
и \myt
, соответственно.
Они не сохраняются на разных уровнях/границах области действия, поэтому команда \getmytransformmatrix
должна появляться в каждой области действия, в которой вы хотите использовать эту информацию.
Кодекс (с краткой иллюстрацией)
\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}
Выход
Обратите внимание, что матрица не «запоминается» за пределами области действия, и что это показывает накопленную трансформацию ( xshift=2pt
из исходной средыи yshift=-5pt
из области действия).
Дополнительные переменные b
и c
могут быть использованы для других вычислений; например, для вычисления эффективного вращения ( atan(\myd/\mya)
будет работать только из (-90,90)).
решение2
Ответ на этот вопрос зависит от того, какова цель сохранения xscale
. Мне приходят в голову две возможности:
- Вы хотите узнать, что было передано через
xscale
. - Вы хотите узнать
xscale
текущую область применения.
Первое довольно просто, второе зависит от того, что вы подразумеваете под xscale
.
Причина, по которой первый вариант не является тривиальным, заключается в том, что TikZ не утруждает себя сохранением переданного вами значения, он просто применяет его и забывает. Поэтому вам нужно добавить обертку вокруг ключа, xscale
которая сохраняет значение для последующего использования. Вот код для этого:
\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}
(Возможно, это не самый элегантный способ добиться этого.)
Трудности со вторым вариантом заключаются в том, что TikZ может применятьсялюбойаффинное преобразование частей рисунка. Поэтому вам нужно придумать значение для xscale
произвольного аффинного преобразования. Рассмотрим два следующих сценария:
Вы применяете
xscale=2
и затем применяете поворот на π/2 (против часовой стрелки). Результирующая матрица —[0 -1] [2 0]
Сначала вы применяете вращение, а затем делаете
yscale=2
. Результирующая матрица[0 -1] [2 0]
Итак, эти две операции приводят к одной и той же матрице. Имеет ли эта матрица xscale
значение , равное 2
или yscale
равное 2
? Или оба 0
?
Теперь рассмотрим вращение и затем xscale=2
. Это дает:
[0 -2]
[1 0]
Итак, для всех этих сценариев вам нужно решить, что xscale
должно быть. Существуют разумные определения, но что именно будет зависеть от того, что вы хотите с ними сделать.
Таким образом, лучшее, что вы можете сделать, это изучить матрицу.в целоми вычислить некоторое число, которое подойдет для того, что вы хотите сделать, но поскольку это не указано в вопросе, то ответить на него не представляется возможным.
Чтобы получить записи самой матрицы (ну, матрицы и перевода), можно использовать команду PGF \pgfgettransformentries
. А потом делайте с ними что хотите. Например, если вы хотите узнатьобщиймасштаб, вы можете взять квадратный корень из абсолютного значения его определителя. Если вы хотите узнать длину вектора, который (1,0)
в конечном итоге станет, вы можете это вычислить.
В итоге:
- Чтобы сохранить накопленные значения, переданные в
xscale
, просто сохраните их перед передачей, - Чтобы извлечь
xscale
из матрицы преобразования, используйте команды PGF для доступа к матрице, выясните, что вы подразумеваете подxscale
произвольной матрицей, а затем вычислите ее из полученных значений.