
Пожалуйста, рассмотрите этот код:
\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}