Расширение макроса "\coord" в команде TikZ "let"

Расширение макроса "\coord" в команде TikZ "let"

Пожалуйста, рассмотрите этот код:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\def\coord(#1){coordinate(#1)}
\begin{document}
\begin{tikzpicture}
    \node[draw](A) at (0,0) {A};
    \node[draw](B) at (3,3) {B};
    % this works
    \draw let \p1=(A), \p2=(B) in (A) -- (\x1, \y2) coordinate(C);
    % this fails
    % \draw let \p1=(A), \p2=(B) in (A) -- (\x1, \y2) \coord(C);
    \node [right] at (C) {\pgfversion};
\end{tikzpicture}
\end{document}

введите описание изображения здесь

Закомментированная строка не работает --- похоже, что в letпути \coordмакрос не развернут. Это ожидаемо?

PD. Я использую это, потому что использую следующий код:

\def\normcoord(#1){coordinate(#1)}
\def\showcoord(#1){node[circle, red, draw, inner sep=1pt,pin={[red, overlay, inner sep=0.5pt, font=\tiny, pin distance=0.1cm, pin edge={red, overlay,}]45:#1}](#1){}}
\let\coord=\showcoord

для переключения между «отмеченными» и «неотмеченными» узлами при построении чертежей.

решение1

Вам просто не повезло, так как вы решили вызвать свой макрос \coord, который уже имеет значение. Он позволяет нам вспомнить, как была определена координата. Так что если вы используете, скажем, \mycoordвместо \coord, ваш код работает так, как и ожидалось. Я также добавил кое-что, что показывает, что \coordделает. Вы можете думать об этом как о кузене \n, \p, \xи \y, которые также имеют особое значение в синтаксисе let ... in. While \pпозволяет вам «установить» точку \xи \yвыдать их экранные координаты и \coordстроку, с помощью которой была определена координата. Более подробно, доступные макросы (взяты из tikzlibrarycalc.code.tex)

  \let\p=\tikz@cc@dop%
  \let\x=\tikz@cc@dox%
  \let\y=\tikz@cc@doy%
  \let\n=\tikz@cc@don%
  \let\rawx=\tikz@cc@dotempx%
  \let\rawy=\tikz@cc@dotempy%
  \let\rawz=\tikz@cc@dotempz%
  \let\coord=\tikz@cc@docoord%

На данный момент он также содержит \rawx, \rawyи \rawz, которые являются компонентами координат, которые использовались для определения координаты.

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\def\mycoord(#1){coordinate(#1)}
\begin{document}
\begin{tikzpicture}
    \node[draw](A) at (0,0) {A};
    \node[draw](B) at (3,3) {B};
    % this works
    \draw let \p1=(A), \p2=(B) in (A) -- (\x1, \y2) coordinate(C);
    % this also works
    \draw let \p1=(A), \p2=(B) in (A) -- (\x1, \y2) \mycoord(C);
    \node [right] at (C) {\pgfversion};
    \path let \p{A}=(A),\p{B}=(B),\p{C}=(C) in
    (0,3) node[anchor=south west,align=left] {Let us show how\\ 
    we were defined:\\$A=\coord{A}$\\
    $B=\coord{B}$\\ $C=\coord{C}$\\};
\end{tikzpicture}
\end{document}

введите описание изображения здесь

Позвольте мне также упомянуть, что \coord, или связанные с ним инструменты, являются незаменимым инструментом в 3D-вычислениях, поскольку экранные координаты всегда являются всего лишь проекциями, т.е. среди прочего вы теряете третий компонент. В какой степени это будет использоваться осмысленным образом, зависит от будущих разработок TiкZ. Основная проблема в том, что на данный момент не фиксируется, в какой системе отсчета была определена координата.

Поскольку Анри Менке попросил меня об этом, я упоминаю, что он решил удалить \coord, \rawx, \rawyи \rawz. IMHO этот шаг излишен и нарушает рабочие коды. Но эта самая проблема может и не возникнуть в будущем.

Однако это вовсе не особая ситуация. Скорее, например, я обычно называю переменные цикла \X, \Yи так далее, просто потому, что синтаксис calc использует и переопределяет \xи \y\xтакже является параметром plot по умолчанию). То есть, \xи \yтакже перезаписываются без предупреждения, и пользователи обычно учатся избегать коллизий, называя свои макросы по-разному. Иногда даже очень простые команды (например, \xi) перезаписываются, но пока вы знаете, что это происходит, вы всегда можете найти способ решить эту проблему. Существует только конечное количество имен макросов. Каждый \foreachцикл перезаписывает свои переменные цикла без предупреждения.

решение2

В PGF 3.1.4 я допустил ошибку, введя новые команды уровня пользователя без их документирования. Эти команды определяются внутри операции letи безоговорочно перезаписывают возможное глобальное определение. Эти локальные макросы

\rawx
\rawy
\rawz
\coord

Это было задумано как эксперимент, который, как теперь доказано, во многих случаях провалился. Поэтому в предстоящем релизе PGF 3.1.5 я снова удалю эти команды. Вы можете восстановить правильное поведение операции, letпереопределив определение в преамбуле после загрузки библиотеки calc.

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\makeatletter
\def\tikz@let@command et{%
  \let\p=\tikz@cc@dop%
  \let\x=\tikz@cc@dox%
  \let\y=\tikz@cc@doy%
  \let\n=\tikz@cc@don%
  \pgfutil@ifnextchar i{\tikz@cc@stop@let}{\tikz@cc@handle@line}%
}%
\makeatother

\def\coord(#1){coordinate(#1)}
\begin{document}
\begin{tikzpicture}
    \node[draw](A) at (0,0) {A};
    \node[draw](B) at (3,3) {B};
    % this works
    \draw let \p1=(A), \p2=(B) in (A) -- (\x1, \y2) coordinate(C);
    % this fails
    \draw let \p1=(A), \p2=(B) in (A) -- (\x1, \y2) \coord(C);
    \node [right] at (C) {\pgfversion};
\end{tikzpicture}
\end{document}

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