Bitte beachten Sie diesen Code:
\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}
Die kommentierte Zeile schlägt fehl – es scheint, dass das Makro im let
Pfad \coord
nicht erweitert wird. Ist das zu erwarten?
PD. Ich verwende dies, weil ich den folgenden Code verwende:
\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
um beim Erstellen von Zeichnungen zwischen „markierten“ und „unmarkierten“ Knoten zu wechseln.
Antwort1
Sie hatten einfach Pech, da Sie sich entschieden haben, Ihr Makro aufzurufen \coord
, das bereits eine Bedeutung hat. Es ermöglicht uns, uns daran zu erinnern, wie eine Koordinate definiert wurde. Wenn Sie also beispielsweise \mycoord
anstelle von verwenden \coord
, funktioniert Ihr Code wie erwartet. Ich habe auch etwas hinzugefügt, das zeigt, was \coord
funktioniert. Sie können es sich als Cousin von \n
, \p
, \x
und vorstellen \y
, die ebenfalls spezielle Bedeutungen in der let ... in
Syntax haben. Während \p
Sie den Punkt „setzen“ \x
und \y
ihre Bildschirmkoordinaten und \coord
die Zeichenfolge ausgeben können, mit der die Koordinate definiert wurde. Genauer gesagt sind die verfügbaren Makros (entnommen aus 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%
Ab sofort enthält es auch \rawx
, \rawy
und \rawz
, die Komponenten der Koordinaten, die zur Definition der Koordinate verwendet wurden.
\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}
Erwähnenswert ist auch, dass \coord
, oder verwandte Tools, bei 3D-Berechnungen unverzichtbar sind, da die Bildschirmkoordinaten immer nur Projektionen sind, d. h. man verliert unter anderem die dritte Komponente. Inwieweit dies sinnvoll genutzt wird, hängt von zukünftigen Entwicklungen von Ti ab.kZ. Das Hauptproblem besteht darin, dass derzeit nicht aufgezeichnet wird, in welchem Frame die Koordinate definiert wurde.
Da Henri Menke mich darum gebeten hat, erwähne ich, dass er beschlossen hat, , , und zu entfernen \coord
. \rawx
Meiner \rawy
Meinung \rawz
nach ist dieser Schritt unnötig und zerstört funktionierende Codes. Aber genau dieses Problem wird in Zukunft vielleicht nicht mehr auftreten.
Dies ist jedoch keineswegs eine besondere Situation. Vielmehr nenne ich beispielsweise Schleifenvariablen normalerweise \X
, \Y
und so weiter, einfach weil die Calc-Syntax und verwendet und neu definiert \x
( \y
und \x
ist auch der Standardplotparameter). Das heißt, \x
und \y
werden ebenfalls ohne Warnung überschrieben, und Benutzer lernen normalerweise, Kollisionen zu vermeiden, indem sie ihre Makros anders benennen. Manchmal werden sogar sehr grundlegende Befehle (z. B. \xi
) überschrieben, aber solange man weiß, dass dies geschieht, kann man immer einen Weg finden, dies zu lösen. Es gibt nur eine begrenzte Anzahl von Makronamen. Jede \foreach
Schleife überschreibt ihre Schleifenvariablen ohne Warnung.
Antwort2
In PGF 3.1.4 habe ich den Fehler gemacht, neue Befehle auf Benutzerebene einzuführen, ohne sie zu dokumentieren. Diese Befehle werden innerhalb der let
Operation definiert und überschreiben bedingungslos eine mögliche globale Definition. Diese lokalen Makros sind
\rawx
\rawy
\rawz
\coord
Es war als Experiment gedacht, das sich inzwischen in vielen Fällen als fehlgeschlagen erwiesen hat. Daher werde ich diese Befehle in der kommenden PGF 3.1.5-Version wieder entfernen. Sie können das korrekte Verhalten der let
Operation wiederherstellen, indem Sie die Definition in Ihrer Präambel nach dem Laden der calc
Bibliothek überschreiben.
\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}