Доступ к опции масштабирования в среде TikZ

Доступ к опции масштабирования в среде TikZ

При использовании опции масштабирования в \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. Мне приходят в голову две возможности:

  1. Вы хотите узнать, что было передано через xscale.
  2. Вы хотите узнать 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произвольного аффинного преобразования. Рассмотрим два следующих сценария:

  1. Вы применяете xscale=2и затем применяете поворот на π/2 (против часовой стрелки). Результирующая матрица —

    [0 -1]
    [2  0]
    
  2. Сначала вы применяете вращение, а затем делаете yscale=2. Результирующая матрица

    [0 -1]
    [2  0]
    

Итак, эти две операции приводят к одной и той же матрице. Имеет ли эта матрица xscaleзначение , равное 2или yscaleравное 2? Или оба 0?

Теперь рассмотрим вращение и затем xscale=2. Это дает:

[0 -2]
[1  0]

Итак, для всех этих сценариев вам нужно решить, что xscaleдолжно быть. Существуют разумные определения, но что именно будет зависеть от того, что вы хотите с ними сделать.

Таким образом, лучшее, что вы можете сделать, это изучить матрицу.в целоми вычислить некоторое число, которое подойдет для того, что вы хотите сделать, но поскольку это не указано в вопросе, то ответить на него не представляется возможным.

Чтобы получить записи самой матрицы (ну, матрицы и перевода), можно использовать команду PGF \pgfgettransformentries. А потом делайте с ними что хотите. Например, если вы хотите узнатьобщиймасштаб, вы можете взять квадратный корень из абсолютного значения его определителя. Если вы хотите узнать длину вектора, который (1,0)в конечном итоге станет, вы можете это вычислить.

В итоге:

  1. Чтобы сохранить накопленные значения, переданные в xscale, просто сохраните их перед передачей,
  2. Чтобы извлечь xscaleиз матрицы преобразования, используйте команды PGF для доступа к матрице, выясните, что вы подразумеваете под xscaleпроизвольной матрицей, а затем вычислите ее из полученных значений.

Связанный контент