Por favor, considere este código:
\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}
A linha comentada falha --- parece que no let
caminho a \coord
macro não está expandida. Isso é esperado?
PD. Eu uso isso porque uso o seguinte código:
\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
para alternar entre nós "marcados" e "não marcados" enquanto construo desenhos.
Responder1
Você só teve azar porque optou por chamar sua macro \coord
, que já tem um significado. Permite-nos recordar como uma coordenada foi definida. Portanto, se você usar, digamos, \mycoord
em vez de \coord
, seu código funcionará conforme o esperado. Também adicionei algo que mostra o que \coord
faz. Você pode pensar nisso como primo de ,, \n
e , que também têm significados especiais na sintaxe. Enquanto permite "definir" o ponto e fornecer as coordenadas da tela e a string pela qual a coordenada foi definida. Mais detalhadamente, as macros disponíveis são (retiradas de )\p
\x
\y
let ... in
\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%
A partir de agora, também contém \rawx
, \rawy
e \rawz
, que são os componentes das coordenadas que foram usadas para definir a coordenada.
\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}
Deixe-me mencionar também que \coord
, ou ferramentas relacionadas, é uma ferramenta indispensável em cálculos 3D já que as coordenadas da tela são sempre apenas projeções, ou seja, entre outras coisas você perde o terceiro componente. Até que ponto isso será usado de forma significativa depende dos desenvolvimentos futuros do TikZ. O principal problema é que, a partir de agora, não fica registrado em qual quadro a coordenada foi definida.
Como Henri Menke me pediu, menciono que ele decidiu remover \coord
, \rawx
, \rawy
e \rawz
. IMHO, esta mudança é desnecessária e quebra os códigos de trabalho. Mas esse mesmo problema pode não aparecer no futuro.
No entanto, esta não é uma situação especial. Em vez disso, por exemplo, geralmente chamo variáveis de loop \X
e \Y
assim por diante, simplesmente porque a sintaxe calc usa e redefine \x
and \y
(e \x
também é o parâmetro de plotagem padrão). Isto é, \x
e \y
também são substituídos sem aviso prévio, e os usuários geralmente aprendem a evitar colisões nomeando suas macros de maneira diferente. Às vezes, até comandos muito básicos (por exemplo, \xi
) são sobrescritos, mas desde que se saiba que isso acontece, sempre é possível encontrar uma maneira de resolver o problema. Existe apenas um número finito de nomes de macro. Cada \foreach
loop sobrescreve suas variáveis de loop sem aviso prévio.
Responder2
No PGF 3.1.4 cometi o erro de introduzir novos comandos em nível de usuário sem documentá-los. Esses comandos são definidos dentro da let
operação e sobrescrevem incondicionalmente uma possível definição global. Essas macros locais são
\rawx
\rawy
\rawz
\coord
Foi concebido como um experimento, que já foi comprovado que falhou em muitos casos. Portanto, na próxima versão do PGF 3.1.5, removerei esses comandos novamente. Você pode restaurar o comportamento correto da let
operação substituindo a definição no seu preâmbulo após carregar a calc
biblioteca.
\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}