Tikz: Pfade (lokal) als Variable oder Ähnliches speichern

Antwort erstellen


Diese Frage dient dazu, das automatisierte Versenden von Formularen durch Spam-Bots zu verhindern.
Smilies
:D :) :( :o :shock: :? 8) :lol: :-x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen:

BBCode ist eingeschaltet
[img] ist eingeschaltet
[flash] ist ausgeschaltet
[url] ist eingeschaltet
Smilies sind eingeschaltet

Die letzten Beiträge des Themas

Ich habe die Datenschutzerklärung gelesen und bin damit einverstanden.

   

Wenn du eine Datei oder mehrere Dateien anhängen möchtest, gib die Details unten ein.

Ansicht erweitern Die letzten Beiträge des Themas: Tikz: Pfade (lokal) als Variable oder Ähnliches speichern

von cgnieder » Sa 3. Dez 2011, 19:13

Wenn man LaTeX (und eben nicht TeX) verwendet, dann würde ich \newcommand und \renewcommand verwenden. Das sind ja genau die LaTeX-Befehle für eigene Makros.

Ob es so einfach ist, sich längeres Zeug, etwa Formeln innerhalb einer Matheumgebung zu speichern und wiederzuverwenden, wage ich zu bezweifeln.
\documentclass{article}
\usepackage{amsmath}
\begin{document}
Geht:
\begin{equation}
 \newcommand\summe{a+b=c}
 \summe
\end{equation}

Geht nicht:
\begin{align}
 \newcommand\summe{d+e&=f}
 \summe \\
 \summe
\end{align}

\end{document}
Ich habe es nicht überprüft, aber es sieht so aus, als ob bei align einzelne Zeilen in einer eigenen Gruppe sind.

von guy.brush™ » Sa 3. Dez 2011, 18:17

Hallo,

sorry für die späte Rückmeldung.

Eine letzte Frage noch: Was würdest du mir empfehlen, \def oder \newcommand?

Irgendwie muss ich da beim Testen damals, ob \def nur lokal oder auch global wirkt, mind. 1 Fehler gemacht haben ... denn ich war fest davon überzeugt, dass es stets global wirkt.

Aber dann kennt LaTeX ja quasi doch lokale Variablen und man kann zur not in einer align(-Umgebung ein längeres Gewirr speichern :). [Noch ungetestet ;).]

von cgnieder » So 27. Nov 2011, 20:19

guy.brush™ hat geschrieben:Tatsächlich, \newcommand und \def wirken nur lokal innerhalb der tikzpicture-Umgebung, scheinbar sogar bei einer einer scope-Umgebung nur lokal innerhalb von der.
Wie gesagt, die Neudefinition findet nur innerhalb einer TeX-Gruppe statt. Möchte man einen Befehl global definieren, muss man das a) in der "äußersten Gruppe" machen:
\documentclass{article}
\def\meinbefehlA{blabla}
\begin{document}
{ \meinbefehlA } \meinbefehlA

\def\meinbefehlB{blablub} { \meinbefehlB } \meinbefehlB
\end{document}
oder b) \gdef verwenden:
\documentclass{article}
\begin{document}
lokal: { \def\meinbefehlA{blabla} \meinbefehlA }% nicht definiert: \meinbefehlA

global: { \gdef\meinbefehlB{blablub} \meinbefehlB } \meinbefehlB
\end{document}
guy.brush™ hat geschrieben:Was wäre denn hier der Vorteil von \def im Vergleich zu \newcommand?
Im Gegensatz zu \def gibt \newcommand einen Fehler aus, wenn man damit einen existierenden Befehl überschreiben würde. Dafür muss man dann bewusst \renewcommand verwenden. Also kann man nicht aus Versehen einen wichtigen Befehl löschen. Bei Namen wie \gewirr sollte das allerdings recht gefahrlos sein.
guy.brush™ hat geschrieben:Und der 2. Vorschlag von dir ist vermutlich tatsächlich etwas "overpowered", aber mal schauen. Hast du das jetzt extra für mich geschrieben?
Hat nur fünf Minuten gedauert...

von guy.brush™ » So 27. Nov 2011, 19:59

Tatsächlich, \newcommand und \def wirken nur lokal innerhalb der tikzpicture-Umgebung, scheinbar sogar bei einer einer scope-Umgebung nur lokal innerhalb von der. Ich war mir aber recht sicher, dass ich schon einmal ausprobierte und das ganze dann global bekannt gewesen wäre. Muss ich damals irgendwas falsch gemacht haben.

Was wäre denn hier der Vorteil von \def im Vergleich zu \newcommand?


Und der 2. Vorschlag von dir ist vermutlich tatsächlich etwas "overpowered", aber mal schauen. Hast du das jetzt extra für mich geschrieben?

von cgnieder » So 27. Nov 2011, 13:46

\def definiert die Befehle nur lokal, also innerhalb einer TeX-Gruppe. Da jede Umgebung eine solche Gruppe öffnet (und wieder schließt) sollte alles, was Du mit \def innerhalb der tikzpicture Umgebung definierst, außerhalb nicht definiert sein.

Wenn Dir \def nicht behagt, kannst Du ja \newcommand verwenden:
\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage[utf8]{inputenc}
\usepackage{tikz}

\begin{document}
 \begin{tikzpicture}
  \def\test{ (0,0) -- (2,3) -- (4,2) -- (3,1)}
  \begin{scope}
    \draw \test -- (5,5);
  \end{scope}
  \begin{scope}[xshift=4cm]
    \draw \test -- (0,0) ;
  \end{scope}
\end{tikzpicture}
% Verwendung hier gibt einen Fehler, da \test nur innerhalb des tikzpictures definiert:
% \test

 \begin{tikzpicture}
  \newcommand\test{ (0,0) -- (2,3) -- (4,2) -- (3,1)}
  \begin{scope}
    \draw \test -- (5,5);
  \end{scope}
  \begin{scope}[xshift=4cm]
    \draw \test -- (0,0) ;
  \end{scope}
\end{tikzpicture}
% Verwendung hier gibt einen Fehler, da \test nur innerhalb des tikzpictures definiert:
% \test
\end{document}
Oder auch eigene Befehle fürs speichern und verwenden (ist aber wohl etwas übertrieben):
\begin{filecontents}{savepath.sty}
\ProvidesPackage{savepath}[2011/11/27 0.1 (nicht nur) TikZ-Pfade speichern]

% für die \ifcsdef und \csundef Befehle:
\RequirePackage{etoolbox}

% Pfad speichern; Fehler, wenn der gleiche Identifier schon verwendet wurde:
\providecommand\savepath[2]{\ifcsdef{path@#1}{\PackageError{savepath}{Pfad `#1' schon gespeichert.}{Der Pfad mit dem Namen `#1' wurde schon gespeichert. Bitte waehlen Sie einen anderen Namen.}}{\@namedef{path@#1}{#2}}}

% Pfad überschreiben; Fehler, wenn er noch definiert wurde:
\providecommand\renewpath[2]{\ifcsdef{path@#1}{\@namedef{path@#1}{#2}}{\PackageError{savepath}{Der Pfad `#1' existiert nicht.}{}}}

% Pfad verwenden; Fehler, wenn er noch nicht definiert wurde:
\providecommand\usepath[1]{\ifcsdef{path@#1}{\@nameuse{path@#1}}{\PackageError{savepath}{Der Pfad `#1' existiert nicht.}{}}}

% Pfad löschen; Warnung,  wenn er noch nicht definiert wurde:
\providecommand\deletepath[1]{\ifcsdef{path@#1}{\csundef{path@#1}}{\PackageWarning{savepath}{Der Pfad `#1' existiert nicht.}{Der Pfad `#1' existiert nicht und kann nicht geloescht werden.}}}
\endinput
\end{filecontents}

\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage[utf8]{inputenc}
\usepackage{tikz,savepath}

\begin{document}

\begin{tikzpicture}
  \savepath{test}{ (0,0) -- (2,3) -- (4,2) -- (3,1)}
  \begin{scope}
    \draw \usepath{test} -- (5,5);
  \end{scope}
  \renewpath{test}{ (0,0) -- (3,2) -- (2,4) -- (1,3)}
  \begin{scope}[xshift=4cm]
    \draw \usepath{test} -- (0,0) ;
  \end{scope}
  \deletepath{test}
  \savepath{test}{\node[below] (test) at (0,0) {test} ;}
  \usepath{test}
\end{tikzpicture}
% Verwendung hier gibt einen Fehler,  da nur innerhalb des tikzpictures definiert:
% \usepath{test}

\end{document}

von guy.brush™ » So 27. Nov 2011, 12:40

Hallo,

vielen Dank erst einmal für deine Antwort :). Aber mir sind ein paar Dinge noch nicht ganz klar. Erst einmal zu deiner Antwort selbst:
bloodworks hat geschrieben:Deine Lösung ist imo nicht so schlecht [...]
Meinst du damit die \def-Variante? \def soll man doch eigentlich nicht verwenden (außer man weiß, wieso man es jetzt unbedingt braucht). Außerdem sind die definierten "Dinger" dann global unter dem Namen verfügbar.
bloodworks hat geschrieben: [...] wenn du deine Punkte benennen willst, musst du die erstmal bekannt machen. Dazu ist das imho einfachste die Koordinaten in einem Makro zu speichern und mehrfach aufzurufen.
Mit Makro meinst du also die \def-Variante (siehe oben)?
bloodworks hat geschrieben:Theoretisch kann tikz auch Pfade speichern [...]
Und wie ginge das? Oder meinst du mithilfe von \def?
bloodworks hat geschrieben:[...] dass das mehrfache definieren von nodes ein Problem geben sollte. Grüße
Die Aussage verstehe ich nicht ganz. Hast du vielleicht ein kurzes Beispiel?


Dann noch zu deinen Lösungsvorschlägen: Also bei der ersten (kleineren) Tikz-Umgebung hast du mich falsch verstanden bzw. ich mich wohl nicht genau genug ausgedrückt.

Mein Anliegen war, dass ich denselben Pfad, den ich im ersten Minimalbeispiel "test" genannt habe, um 10 nach rechts geshiftet, noch einmal zeichnen lasse und zusätzlich noch eine weitere Strecke zur Koordinate (5,5) (also eigentlich, wegen Shift, (15,15)) anhänge. Die beiden Pfade sollten eigentlich nicht zusammenhängend sein :).

[Wenn ich nämlich einen extra \fill ausführe, dann verwende ich zwar dengleichen Pfad, aber nicht denselben *g*. Ich hänge mein \fill also nicht an die gezeichnete Linie dran, sondern der Rahmen des \fill läuft den Pfad selbst noch einmal ab und hängt dann hinten noch einen weiteren Weg mit dran. Bildlich gesprochen: Ein Männlein läuft vorweg und malt die Grenzlinien, dann läuft ein weiteres Männlein den inneren Weg hinterher und füllt nach innen die Farbe in das Gebiet hinein. Am Rand des Gebiets ist das zweite Männlein frech und geht über die Grenze hinaus und malt kräftig weiter, bis es zum Ursprungspunkt zurückkommt. Dann geht ein drittes Männlein her und nimmt eine riesen, beliebig geformte, Plätzchenaussteckform und trennt die überstehende Farbe vom eigentlichen Gebiet ab (das wäre dann \clip).]

Zum zweiten Lösungsvorschlag: Erst einmal, der Name "dreck" für "Dreieck" ist witzig :D. Ich glaube, ich verstehe, was du machst, bin aber noch etwas verwirrt, warum deine Variante "besser" sein sollte, als die Variante, die ich hatte (mit \def). Ach ... ich sehe gerade, ich habe das gar nicht komplet angepasst *g*. Hier ist ein Beispiel, wie ich es meinte:
\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage[latin1]{inputenc}
\usepackage{tikz}
\usetikzlibrary{matrix,arrows,intersections,calc}

\begin{document}

\begin{figure}[!ht]
  \centering
  \begin{tikzpicture}
    % Ist die Formatierung im Folgenden so in Ordnung oder kann das zu Problemen führen?
    \def\gewirrpath{(0,7.42) -- (0,6)
         -- (-1,5.5)
         -- (0.1,4.2)
         -- (0.1,2.1)
         -- (2.1,2.1)
         -- (3,2.5)
         -- (2,1.7)
         -- (2,1)
         -- (0,0.5)
         -- (0,0)}
    \begin{scope}[fill=blue!42]
      \fill[clip] (-5,0) -- (5,0) -- (0,7.42) -- cycle;
     
      \fill[red!42] \gewirrpath -- (0,-1)
				-- (6,-1)
				-- (6,7.42);
      % horizontaler Strich im Dreieck (clipped)
      \draw (2,1.7) -- (4.2,1.7);
    \end{scope}
   
    % Dreieck
    \draw[very thick] (-5,0) -- (5,0) -- (0,7.42) -- cycle;
   
    % komisches Gewirr im inneren des Dreiecks
    \draw[name path=gewirr] \gewirrpath;
  \end{tikzpicture}
  \caption{Kurioses Dreieck}
  \label{fig:kurioses_dreieck}
\end{figure}

\end{document}
Wenn du den \clip-Befehl auskommentierst, siehst du, wie ich das mit dem Füllen meine. Zum Glück wird nachher das Bild nur auf den sichtbaren Bereich zentriert und es zählt nicht auch noch das zum Bild, was "weggeclipped" wurde :).

Aber genau das wollte ich eben erreichen, indem ich beim Konstruieren des \fill-Befehls eben vorher kein \def brauche (global definiert), sondern mit z.B. "(gewirr)" arbeiten kann, was mein "name path" davon ist. Oder eine andere, ähnliche Lösung.

[Bei dir fehlt übrigens der horizontale Strich, aber ich habe ihn jetzt nicht genau suchen wollen, vermutlich fehlt der nur irgendwo im Code und wurde nicht "übermalt" ... aber das sollte kein Problem darstellen.]


Viele Grüße,

\\ guy.brush

von bloodworks » So 27. Nov 2011, 12:00

Hallo du kannst natürlich leere nodes einsetzten und diese benennen.
Deine Lösung ist imo nicht so schlecht, wenn du deine Punkte benennen willst, musst du die erstmal bekannt machen. Dazu ist das imho einfachste die Koordinaten in einem Makro zu speichern und mehrfach aufzurufen. Theoretisch kann tikz auch Pfade speichern, ich halte es so aber für übersichtlicher und mir wäre nciht bekannt, dass das mehrfache definieren von nodes ein Problem geben sollte. Grüße
\documentclass{scrartcl} 
\usepackage[T1]{fontenc} 
\usepackage[ngerman]{babel} 
\usepackage[latin1]{inputenc} 
\usepackage{tikz} 
\usetikzlibrary{matrix,arrows,intersections,calc} 

\begin{document} 

\begin{tikzpicture} 
   \draw (0,0) -- (2,3) -- (4,2)node (anderer Test) {} -- (3,1) node(test) {}; 
   \begin{scope}[xshift=10] 
     \draw (test.center) -- (5,5)--(anderer Test.center);  % so funktioniert das   
   \end{scope} 
\end{tikzpicture} 



 
 
   \begin{tikzpicture} 
  
%     \draw (-5,0) -- (5,0) -- (0,7.42) -- cycle; 


\def\gewirr{(0,7.42) -- (0,6) 
          -- (-1,5.5) 
          -- (0.1,4.2) 
          -- (0.1,2.1) 
          -- (2.1,2.1) 
          -- (3,2.5) 
          -- (2,1.7) node(d) {}
          -- (2,1) node(c) {}
          -- (0,0.5) node(b) {}
          -- (0,0) node(a) {} }       
\def\dreck{(-5,0) node(li u) {}-- (5,0)node(re u){} -- (0,7.42) -- cycle}

 \begin{scope}[fill=blue!42]
       \fill[clip] (-5,0) -- (5,0) -- (0,7.42) -- cycle; 
     
     % Dreieck 
      \path \dreck; 
        \path\gewirr ;
                         \fill[red!42] (a.center)--(b.center)--(c.center)--(d.center)--(8,1.7)--(re u.center)--(a.center) --cycle; 
                 \draw \gewirr ; 
                 \draw[very thick] \dreck;
          \end{scope}
  %die 8,1.7 solltest du dir natürlich auerechnen. 


   \end{tikzpicture}
   
   
   
   
\end{document} 
  

Tikz: Pfade (lokal) als Variable oder Ähnliches speichern

von guy.brush™ » Sa 26. Nov 2011, 22:04

Hallo,

ich hätte eine weitere kleine Frage. Und zwar möchte ich (kompliziertere) Pfade, die ich gezeichnet habe, gerne irgendwie lokal unter einem Namen oder einer Variablen speichern, um später auf sie leichter zugreifen zu können. Eigentlich möchte ich erreichen, dass ich später mithilfe der Variable den Pfad einfach noch einmal zeichnen kann.
\documentclass[a4paper,%
	       11pt,%
	       DIV=10,%
	       BCOR=0mm,%
	       twoside=semi,%
	       footnotes=multiple]{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{matrix,arrows,intersections,calc}

\begin{document}

\begin{tikzpicture}
  \draw[name path=test] (0,0) -- (2,3) -- (4,2) -- (3,1);
  \begin{scope}[xshift=10]
    \draw (test) -- (5,5);  % so funktioniert das nicht :(
  \end{scope}
\end{tikzpicture}

\end{document}
Der Grund ist einfach: Um, wie hier ursprünglich gefragt, komplexere Gebilde unterschiedlich einzufärben, kann es nötig sein, den \fill Befehl getrennt vom gezeichneten Rand (\draw) auszuführen. Unter gerade genannten Link habe ich es z.B. so gemacht, dass ich ein gefärbtes Gebilde genommen habe, dass dieselbe "Strecke" innerhalb des Dreiecks zurücklegt wie das "Gewirr" im Inneren. Außerhalb des Dreiecks einfach beliebig vergrößern und dann mit einem \clip in der Dreiecksform abschneiden. Ich hoffe, es ist verständlich, was ich meine ;). Es sieht dann etwa wie folgt aus:
\begin{figure}[!ht]
  \centering
  \begin{tikzpicture}
    \def\gewirrpath{(0,7.42) -- (0,6)
		   -- (-1,5.5)
		   -- (0.1,4.2)
		   -- (0.1,2.1)
		   -- (2.1,2.1)
		   -- (3,2.5)
		   -- (2,1.7)
		   -- (2,1)
		   -- (0,0.5)
		   -- (0,0)}
%     \draw (-5,0) -- (5,0) -- (0,7.42) -- cycle;
    \begin{scope}[fill=blue!42]
      \fill[clip] (-5,0) -- (5,0) -- (0,7.42) -- cycle;
      
      \fill[red!42] (2,1.7) -- (4.2,1.7)
		    -- (5.5,1.7)
		    -- (5.5,-1)
		    -- (0,-1)
		    -- (0,0)
		    -- (0,0.5)
		    -- (2,1)
		    -- cycle;
      % horizontaler Strich im Dreieck (clipped)
      \draw (2,1.7) -- (4.2,1.7);
    \end{scope}
    
    % Dreieck
    \draw[very thick] (-5,0) -- (5,0) -- (0,7.42) -- cycle;
    
    % komisches Gewirr im inneren des Dreiecks
    % Ist die Formatierung im Folgenden so in Ordnung oder kann das zu Problemen führen?
    \draw[name path=gewirr] \gewirrpath;
    \begin{scope}[yshift=-10cm]
      \draw \gewirrpath;
    \end{scope}
%       \draw (gewirr) -- (6,4) -- cycle;
  \end{tikzpicture}
  \caption{Kurioses Dreieck}
  \label{fig:kurioses_dreieck}
\end{figure}
Hier habe ich noch \def verwendeet, aber diese Lösung dürfte nicht sonderlich schön sein :).


Viele Grüße,

\\ guy.brush

Nach oben