Ich sollte anmerken, dass ich mit TikZ bereits vertraut bin und nach technischen Antworten suche, als ob TikZ nicht technisch genug wäre.
Diese Frage läuft auf die folgende Frage hinaus: Was ist der Unterschied zwischen diesen Dingen:
\def\pointA{\pgfpoint{0cm}{0cm}}
\coordinate (A) at (current page.north east);
\coordinate (A) at (1,1);
(current page.north east)
\node [anchor=east] {}
<-- ein Anker? :-p(zeigt nur die Überschneidung der Begriffe)\pgfpointanchor
<-- aber das muss doch wirklich ein Anker sein, oder ist das ein Punkt? :-p
Ich glaube, mein Verständnis ist mangelhaft und beeinträchtigt meine unten gezeigten Versuche.
In Mathematik
APunktist definiert als:
Ein Punkt ist eine exakte Position oder ein Ort auf einer ebenen Fläche. Es ist wichtig zu verstehen, dass ein Punkt kein Ding, sondern ein Ort ist.
AKoordinateist definiert als:
Koordinaten sind eine geordnete Menge von Zahlen, die die Position eines Punkts definieren.
Ein Anker ist:
Dies möchte ich anhand praktischer Beispiele verdeutlichen.
Definieren wir eine Koordinate:
\coordinate (rightmid) at ($ (current page.north east) + (0,-18cm) $); % use tikz calc library
Es gibt viele implizite Koordinaten (sollten sie Koordinaten, Punkte, Anker oder etwas anderes genannt werden?), wie zum Beispiel:
- (aktuelle Seite.Nordwest)
- (aktuelle Seite.Nord)
- (aktuelle Seite.Nordost)
- (aktuelle Seite.Ost)
- (aktuelle Seite.Südosten)
- (aktuelle Seite.Süden)
- (aktuelle Seite.Südwesten)
- (aktuelle Seite.Mitte)
Nehmen wir an, ich möchte den vertikalen Abstand zwischen zwei Dingen berechnen (ich wähle das Wort „Dinge“ mit Absicht) UND diese Variable für die Verwendung außerhalb des aktuellen Bereichs speichern.
zB sind die beiden Dinge (current page.north east) und (rightmid)
Zum Rechnen kenne ich folgende Möglichkeiten (sind das alle?):
Ich könnte verwenden
\pgfmathparse
, um die Arithmetik auszuwertenIch könnte die
\path let \p1=
Syntax verwenden.
Mit Option 1 kann ich , auf und für die Berechnungen setzen \pgfxa
und \pgfya
das \pgfx
Ergebnis \pgfy
mit erhalten \pgfmathresult
.
Ich kann dann eine eindeutige Länge (global) definieren, z. B. \setlength{\mylength}{2cm}
. Ich kann \mylength
sie dann abrufen. Dadurch kann ich nicht alles in ein in sich geschlossenes Makro schreiben, da \setlength
es nur einmal definiert werden kann. Eine Alternative ist die Verwendung von \global\let\mylength{2cm}
, was mir für die Aufgabe besser geeignet erscheint (korrigieren Sie mich, wenn ich falsch liege. Hat dies Auswirkungen auf den Wert+Einheit/Dimension)?
Alles zusammenfügen
- Ist es möglich, anhand der Breite eines TikZ-Knotens die Breite eines anderen zu berechnen?
- Wie kann ich eine Koordinate in einen PGF-Punkt umwandeln und umgekehrt?
- Koordinaten A, B: Berechnen Sie |BA| und den Winkel zwischen +x und (BA)
- pgf-Makro, das einen Knoten zurückgibt
Hier ist ein Experiment, daskompiliert nichtbasierend auf ein paar Antworten:
\documentclass{article}
\usepackage{fontspec}
\usepackage{tikz}
\usetikzlibrary{calc}
% A4 Paper
\pdfpagewidth=210mm \pdfpageheight=297mm % for PDF output
\paperwidth=210mm \paperheight=297mm % for TikZ
\newcommand{\getdistance}[3]{
\makeatletter
% Syntax: <length variable/macro> <coordinate1> <coordinate2>
\pgfpointdiff{\pgfpointanchor{#2}{center}} % https://tex.stackexchange.com/a/39325/13552
{\pgfpointanchor{#3}{center}} % https://tex.stackexchange.com/a/39325/13552
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\pgfmathparse{veclen(\pgf@xa,\pgf@ya)}
\global\let#1\pgfmathresult % <-- I want the pgfmathresult to be a dimension like 510 pt
\makeatother
}
\begin{document}
\begin{tikzpicture}[overlay]
\coordinate (rightmidtest) at ($ (current page.north east) + (0,-10cm) $); % use tikz calc library
\coordinate (rightmid) at ($ (current page.north east) + (0,-18cm) $); % use tikz calc library
\end{tikzpicture}
\getdistance{\globalresult}{rightmidtest}{rightmid}
\getdistance{\globalresult}{current page.north east}{rightmid}
\getdistance % <-- Should expand to last distance measured
\end{document}
Aktualisierter Code 2016-02-25Arbeiten
Nach der Analyse und dem neuen Verständnis aus Percusses Antwort ist mir etwas anderes eingefallen.
Erinnern:
(current page)
ist implizit- anchor .center ist implizit in TikZ, aber nicht in PGF
\pgfpointanchor{<ref>}{<anchor e.g. center>}
Ich habe xparse
für das Makro Syntax verwendet, da diese leichter zu lesen ist.
\documentclass{article}
\usepackage{fontspec}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{xparse}
\makeatletter
\NewDocumentCommand{\getdistance}{ m m O{center} m O{center} }{%
%Syntax: {\<macro>} {<ref1>} [<anchor>] {<ref2>} [<anchor>]
\pgfpointdiff{\pgfpointanchor{#2}{#3}}% https://tex.stackexchange.com/a/39325/13552
{\pgfpointanchor{#4}{#5}}% https://tex.stackexchange.com/a/39325/13552
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\pgfmathparse{veclen(\pgf@xa,\pgf@ya)} % result as number (floating point)
%\pgfmathveclen{\pgf@xa}{\pgf@ya} % alternate syntax to pgfmathparse: result as number (floating point)
%\global\let#1\pgfmathresult pt % does not recognize pt.
\global\edef#1{\pgfmathresult\ pt}
%\pgfmathprintnumber{\pgfmathresult}%
}
\makeatother
\begin{document}
\begin{tikzpicture}[remember picture,overlay]
% (current page) is implicit
% .center is implicit in TikZ but not in PGF \pgfpointanchor{<ref>}{<anchor e.g. center>}
\coordinate (referral1) at ($ (current page.north east) + (0,-18cm) $); % use tikz calc library
\node [minimum height=2cm] (referral2) {};
\end{tikzpicture}
\begin{tikzpicture}[remember picture,overlay]
\getdistance{\globalresultA}{current page}{referral1}
\getdistance{\globalresultB}{current page}[north east]{referral1}
\getdistance{\globalresultC}{current page}[north east]{referral2}[north]
\getdistance{\globalresultD}{current page}[north east]{referral2}[south]
\end{tikzpicture}
\globalresultA
\globalresultB
\globalresultC
\globalresultD
\end{document}
Antwort1
Ich denke, die Verwirrung rührt daher, dass TikZ mit Verweisen und nicht mit Objekten arbeitet. Wenn ein bestimmter Knotenname a
erwähnt wird, geht es normalerweise davon aus, dass der Benutzer wahrscheinlich dessen Mittelpunktskoordinate meint. Oder beim Zeichnen von Dingen zwischen zwei Dingen, wenn eines davon ein Knoten ist, berechnet es den Punkt an seiner Grenze auf magische Weise, sodass der Benutzer es nicht bemerkt.
Aber all das geschieht intern. Und nichts hat etwas mit Knoten oder anderem zu tun. Ein Knoten hat einen Namen, auf den Sie verweisen können, und vordefinierte Orte, an denen er ihn versteht.
Nichts davon wird gespeichert. Sie werden einfach auf ihre Existenz geprüft oder einfach ausgeführt. Mit anderen Worten, wenn Sie schreiben shape=duck
, werden nicht alle möglichen Formnamen durchgegangen, sondern es wird einfach eine Existenzprüfung dieser Art durchgeführt (ich verwende unsinnige Namen für die eigentlichen Makros).
\pgfutil@ifdefined\pgf@Shape@#1@...{<if it exists use>}{<if not err>}
Bei Ankern verhält es sich genauso. Wenn Sie sagen anchor=heel
, wird über „“ nach diesem Namen gefragt \pgf@sh@#1@anchor@#2
und so weiter.
Woher kommen diese nun? Sie werden bei der Shape-Deklaration über \savedanchor
und \anchor
und so weiter definiert.
Sie sind also da und sorgfältig angeordnet, sodass, wenn Sie darauf verweisen, alles von der Breite und Höhe des Textfelds bis zum Formpfad mühsam von Hand codiert wird. Deshalb ist es eine sehr mühsame Arbeit, neue Formen zu definieren. Und wenn Sie darauf verweisen, sind sie so angeordnet, dass die Ankerposition (global!) in die Längenregister geschrieben wird\pgf@<x,y>
Um es kurz zu machen: Wenn Sie sich auf einen Knotenanker beziehen, ist es eigentlich ein ziemlich kompliziertes Verfahren, daraus eine Koordinate zu erhalten.
Darüber hinaus besteht ein Unterschied zwischen einer Koordinate, die ist, \pgf@<x,y>
und einem Knoten vom Koordinatentyp, der ist \coordinate
.
Wenn Sie sich schließlich auf einen Knoten beziehen, versucht TikZ Ihnen zu helfen, indem es davon ausgeht, dass Sie dessen Mittelpunktanker gemeint haben, sodass Sie einige Tastenanschläge sparen können. Gelegentlich müssen Sie jedoch feinere Operationen durchführen, wie etwa Entfernungsmessungen.
Mit Verweisnamen kommen Sie nicht davon. Sie benötigen tatsächliche Koordinaten (wiederum keine \coordinate
S). Wie Mark Wibrow anmerkte, müssen Sie den Kontext irgendwie verstehen, und das geschieht, indem Sie \pgf@process
solche Fragen beantworten: Ist es eine wörtliche Koordinate (1,1)
, ist es ein Knotenname, ist es ein Knotenanker usw. Dann können Sie die resultierenden \pgf@<x,y>
Register verwenden.
Dann können Sie damit machen, was Sie wollen. Ihre Beispielsyntax let
vereinfacht dies ebenfalls erstaunlich gut, tut aber immer noch das, was Sie beschrieben haben. Eigentlich lautet Ihre Frage im Wesentlichen, warum TikZ auf PGF basiert. Es ist ein sehr gut gestaltetes Frontend für eine sehr ausführliche, aber leistungsstarke Syntax von PGF.
Antwort2
\def\pointA{\pgfpoint{0cm}{0cm}}
Verwenden Sie dies nur, wenn Sie mit PGF (der Grundlage von Ti) vertraut sindkZ). Es ist jedoch nicht wichtig, was \pgfpoint
in TeX geschieht; dieser Befehl steht nie allein. Normalerweise ist er Teil der Syntax, zum Beispiel
\coordinate (A) at (current page.north east);
gibt einem Punkt einen Namen. Die tatsächlichen x- und y-Koordinaten sind dabei unwichtig. Wir wissen, wo sich der (A)
Punkt befindet, und das ist alles, was wir wissen müssen.
\coordinate (A) at (1,1);
Ähnlich wie der vorherige. Normalerweise benennen wir Punkte, um (A) die Codelänge/Komplexität zu reduzieren und (B) die Lesbarkeit zu verbessern. Zum Beispiel
(current page.north east)
In Klammern wird einziehen nachAktion. Es ist so, als ob Sie, einen Stift haltend, Ihre Hand zur nächsten Stelle bewegen, an der Sie etwas zeichnen möchten. Zum Beispiel
Dieser Code macht TikZ bewegt den Stift über die gesamte Leinwand und deklariert Knoten/Koordinaten.
\node [anchor=east] {}
Platzieren Sie einen Knoten „in der Nähe“ der aktuellen Position des Stifts. Mit „in der Nähe“ meine ich, dass der von Ihnen angegebene Anker mit der Position des Stifts übereinstimmen sollte. Das ist ähnlich, wie wenn Sie auf einem Boot den Anker dorthin werfen können, wo Sie wollen, und dieser Anker wird dann das Boot fixieren.
praktischer Teil
- du brauchst
\makeatletter
. - Sie möchten wahrscheinlich
\pgfmathsetlength
anstelle von\pgfmathsetmacros
oder\pgfmathparse
.- Denken Sie jedoch daran, dass alle Abmessungen vor der Verwendung angegeben werden müssen.
- Seien Sie vorsichtig, wenn Sie den Knoten verwenden
(current page)
. Normalerweise benötigen Sie[overlay]
. - Sie müssen sich innerhalb einer
tikzpicture
Umgebung befinden, um alles abzurufen, was Sie in einertikzpicture
Umgebung erstellt haben.- Wenn Sie die Arbeit nicht in derselben
tikzpicture
Umgebung erledigen, benötigen Sie[remember picture]
.
- Wenn Sie die Arbeit nicht in derselben
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
\newcommand{\getdistance}[3]{
% Syntax: <length variable/macro> <coordinate1> <coordinate2>
\pgfpointdiff{\pgfpointanchor{#2}{center}} % http://tex.stackexchange.com/a/39325/13552
{\pgfpointanchor{#3}{center}} % http://tex.stackexchange.com/a/39325/13552
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\pgfmathparse{veclen(\pgf@xa,\pgf@ya)}
\global\let#1\pgfmathresult % <-- I want the pgfmathresult to be a dimension like 510 pt
}
\begin{document}
\begin{tikzpicture}[remember picture,overlay]
\coordinate (rightmidtest) at ($ (current page.north east) + (0,-10cm) $); % use tikz calc library
\coordinate (rightmid) at ($ (current page.north east) + (0,-18cm) $); % use tikz calc library
\end{tikzpicture}
\tikz[remember picture,overlay]{
\getdistance{\globalresulta}{rightmidtest}{rightmid}
\getdistance{\globalresultb}{current page}{rightmid}
}
\globalresulta
\globalresultb
\end{document}
Antwort3
\def\pointA{\pgfpoint{0cm}{0cm}}
Dies ist im Grunde dasselbe wie
\coordinate (A) at (0,0);
\coordinate (A) at (current page.north east);
Hier benennen Sie einfach die obere rechte Ecke der Seite als
A
. Das ist sinnlos, da der Ort bereits benannt ist, aber es kann hilfreich sein, nicht alles eintippen zu müssen und einfach zu schreibenA
.\coordinate (A) at (1,1);
Koordinaten in TikZ sind im Grunde Knoten mit der
coordinate
Form, sie benötigen keine Beschriftung und, was besonders wichtig ist, sie haben keinsep
. Das ist also ein Punkt. Trotzdem ist das Schreiben\node[coordinate] (a) at (0,0) {};
gleichbedeutend mit\coordinate (a) at (0,0);
(current page.north east)
Dies zeigt die obere rechte Ecke der aktuellen „Seite“ an. Normalerweise ist dies eine A4-Seite, aber es kann jede beliebige Größe haben. Mit Seite ist in diesem Fall nicht unbedingt das übliche Blatt Papier gemeint, sondern es kann jeder beliebige Bereich sein.
\node [anchor=east] {}
<-- ein Anker?Nein, dies ist kein Anker. Es ist ein Knoten, dessen Positionierung durch die Platzierung des entworfenen Ankers an der Koordinate bestimmt wird. Daher
\node [anchor=east] at (4,0) {};
wird der Knoten, desseneast
Anker mit der Koordinate übereinstimmt, platziert(4,0)
.
Antwort4
Ich weiß nicht, wie ich meine alte Antwort bearbeiten kann. Ich werde einfach eine neue schreiben.
In TikZ Es gibt viele Möglichkeiten, Punkte anzugeben
Geben Sie numerische Koordinaten ein.
Zum Beispiel(1,2)
,(3mm,4in,5pt)
,(6:7)
,(axis cs:x=8)
.Geben Sie den vordefinierten Knotennamen und Ankernamen ein.
Zum Beispiel(current page.south east)
,(current bounding box.north west)
.Geben Sie den vordefinierten Knotennamen an.
Zum Beispiel(current page)
. Dies entspricht(current page.center)
Geben Sie vordefinierte an
coordinate
.
Zum Beispiel\coordinate(X)at(1,2);\path(X);
. Acoordinate
ist eigentlich ein Knoten, dessen Anker „verschwinden“:(X)
,(X.center)
,(X.south)
, und(X.34)
alle liefern dasselbe Ergebnis.
Ihre PGF-Gegenstücke sind
\pgfpointxy
,\pgfpointxyz
,\pgfpointpolar
, und so weiter\pgfpointanchor{#1}{#2}
\pgfpointanchor{#1}{center}
\pgfpointanchor{#1}{center}
Nun sehen Sie \getdistance
, dass in der Definition von nur ein Knotenname eingetragen werden kann und der Anker center
obligatorisch gewählt werden muss. Daher
\getdistance{\globalresultb}{current page.north east}{rightmid}
wird nicht kompiliert, da current page.north east
es sich nicht mehr um einen Knoten handelt. Aber
\coordinate (A) at (current page.north east);
\getdistance{\globalresultb}{A}{rightmid}
wird kompiliert, da (A)
dies der Name eines Knotens ist.
Es liegt an Ihnen, welche Art von Eingabe \getdistance
verarbeiten kann. Zum Beispiel in TikZ kann sowohl als \tikz@parse@node
auch verarbeiten , aber nicht . Allgemeiner können und , , und verarbeiten . Noch allgemeiner können sie verarbeiten . Sie müssen sich für eines entscheiden.(X)
(Y.Z)
(1,2)
\tikz@@scan@@no@calculator
(X)
(Y.Z)
(1,2)
\tikz@@@scan@@absolute
($ (current page.north east) + (0,-10cm) $)