Erweiterung des Makros „\coord“ im TikZ-Befehl „let“

Erweiterung des Makros „\coord“ im TikZ-Befehl „let“

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}

Bildbeschreibung hier eingeben

Die kommentierte Zeile schlägt fehl – ​​es scheint, dass das Makro im letPfad \coordnicht 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 \mycoordanstelle von verwenden \coord, funktioniert Ihr Code wie erwartet. Ich habe auch etwas hinzugefügt, das zeigt, was \coordfunktioniert. Sie können es sich als Cousin von \n, \p, \xund vorstellen \y, die ebenfalls spezielle Bedeutungen in der let ... inSyntax haben. Während \pSie den Punkt „setzen“ \xund \yihre Bildschirmkoordinaten und \coorddie 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, \rawyund \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}

Bildbeschreibung hier eingeben

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. \rawxMeiner \rawyMeinung \rawznach 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, \Yund so weiter, einfach weil die Calc-Syntax und verwendet und neu definiert \x( \yund \xist auch der Standardplotparameter). Das heißt, \xund \ywerden 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 \foreachSchleife ü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 letOperation 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 letOperation wiederherstellen, indem Sie die Definition in Ihrer Präambel nach dem Laden der calcBibliothek ü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}

verwandte Informationen