Auf golatex.de wurde die Frage gestellt, wie man zu einem bereits definierten shape weitere Anker hinzufügen kann. Konkret sollen zu einem rectangle zusätzliche Anker definiert werden, die bei jeweils 1/3 und 2/3 der Seitenlängen liegen.

Hier ist das bereits definierte rectangle

alt text

Code (im wesentlichen aus dem pgfmanual):

Open in writeLaTeX
\documentclass[tikz,margin=5mm]{standalone}

\tikzset{
shape example/.style= {color = black!30,draw,fill = yellow!30,
  line width = .5cm,inner xsep = 2.5cm,inner ysep = 0.5cm}
}

\begin{document}
\Huge
\begin{tikzpicture}
  \node[name=s,shape=rectangle,shape example] {Rectangle\vrule width 1pt height 2cm};
% bisherige Anker einzeichnen lassen
  \foreach \anchor/\placement in
    {north west/above left, north/above, north east/above right,
      west/left, center/above, east/right,
      mid west/right, mid/above, mid east/left,
      base west/left, base/below, base east/right,
      south west/below left, south/below, south east/below right,
      text/left, 15/right,150/above}
    \draw[shift=(s.\anchor)] plot[mark=x] coordinates{(0,0)}
      node[\placement,font=\scriptsize] {\texttt{(s.\anchor)}};
\end{tikzpicture}
\end{document}

Wie kann ich mir jetzt ein shape definieren, das zusätzlich die Anker north 1/3, north 2/3 etc. hat?

gefragt 25 Jun '14, 18:06

esdd's gravatar image

esdd
14.2k53251
Akzeptiert: 87%


Zunächst lohnt ein Blick in die Datei pgfmoduleshapes.code.tex in der das rectangle definiert wird. Dann definiere ich mir ein neues shape myrectangle und übernehme mit Hilfe von \inherit... Befehlen die Anker und den Pfad des rectangle:

Open in writeLaTeX
\pgfdeclareshape{myrectangle}{
  % es wird zunächst alles vom rectangle übernommen
  \inheritsavedanchors[from=rectangle]
  \inheritanchorborder[from=rectangle]
  \foreach \a in {%
      center,mid,base,north,south,west,east,%
      north west,mid west,base west,south west,%
      north east,mid east,base east,south east%
    }{\inheritanchor[from=rectangle]{\a}}
  \inheritbackgroundpath[from=rectangle]
}

Für das rectangle sind zwei saved anchors definiert: \southwest und \northeast. Die beiden können benutzt werden, um weitere Anker zu definieren. Dabei hilft es auch wieder, wenn man sich im Quelltext anschaut, wie die anderen Anker definiert wurden. Zu beachten ist dabei, dass die Koordinaten von \southwest negativ sind, da der Ursprung des nodeeigenen Koordinatensystems beim Anker text liegt.

Der Anker north 2/3 kann zum Beispiel so definiert werden:

Open in writeLaTeX
\anchor{north 2/3}{
  \southwest\pgf@xa=\pgf@x
  \northeast\pgfmathsetlength\pgf@x{\pgf@x-(\pgf@x-\pgf@xa)/3}
}

Dabei wird zunächst die x-Koordinate des \southwest Ankers in \pgf@xa gespeichert. Danach wird mit Hilfe von diesem gespeicherten Wert und der x-Koordinate des \northeast Ankers die Gesamtlänge der oberen Kante bestimmt und ein Drittel dieser Gesamtlänge von der x-Koordinate des \northeast Ankers abgezogen. Die y-Koordinate des Ankers north 2/3 stimmt dagegen schon mit der y-Koordinate von \northeast überein, so dass für diese keine Berechnungen notwendig sind.

alt text

Code:

Open in writeLaTeX
\documentclass[tikz,margin=5mm,convert=false]{standalone}
\makeatletter
\pgfdeclareshape{myrectangle}{
  % es wird zunächst alles vom rectangle übernommen
  \inheritsavedanchors[from=rectangle]
  \inheritanchorborder[from=rectangle]
  \foreach \a in {%
      center,mid,base,north,south,west,east,%
      north west,mid west,base west,south west,%
      north east,mid east,base east,south east%
    }{\inheritanchor[from=rectangle]{\a}}
  \inheritbackgroundpath[from=rectangle]
  % dann werden die zusätzlichen Anker ergänzt
  \anchor{north 1/3}{
    \southwest\pgf@xa=\pgf@x
    \northeast\pgfmathsetlength\pgf@x{\pgf@xa-(\pgf@xa-\pgf@x)/3}
  }
  \anchor{north 2/3}{
    \southwest\pgf@xa=\pgf@x
    \northeast\pgfmathsetlength\pgf@x{\pgf@x-(\pgf@x-\pgf@xa)/3}
  }
  \anchor{south 1/3}{
    \northeast\pgf@xa=\pgf@x
    \southwest\pgfmathsetlength\pgf@x{\pgf@x-(\pgf@x-\pgf@xa)/3}
  }
  \anchor{south 2/3}{
    \northeast\pgf@xa=\pgf@x
    \southwest\pgfmathsetlength\pgf@x{\pgf@xa-(\pgf@xa-\pgf@x)/3}
  }
  \anchor{east 1/3}{
    \southwest\pgf@ya=\pgf@y
    \northeast\pgfmathsetlength\pgf@y{\pgf@ya-(\pgf@ya-\pgf@y)/3}
  }
  \anchor{east 2/3}{
    \southwest\pgf@ya=\pgf@y
    \northeast\pgfmathsetlength\pgf@y{\pgf@y-(\pgf@y-\pgf@ya)/3}
  }
  \anchor{west 1/3}{
    \northeast\pgf@ya=\pgf@y
    \southwest\pgfmathsetlength\pgf@y{\pgf@y-(\pgf@y-\pgf@ya)/3}
  }
  \anchor{west 2/3}{
    \northeast\pgf@ya=\pgf@y
    \southwest\pgfmathsetlength\pgf@y{\pgf@ya-(\pgf@ya-\pgf@y)/3}
  }
}
\makeatother

\tikzset{
  shape example/.style= {color = black!30,draw,fill = yellow!30,
    line width = .5cm,inner xsep = 2.5cm,inner ysep = 0.5cm}
}

\begin{document}
\Huge
\begin{tikzpicture}
  \node[name=s,shape=myrectangle,shape example] {Rectangle\vrule width 1pt height 2cm};
  % bisherige Anker einzeichnen lassen
  \foreach \anchor/\placement in
    {north west/above left, north/above, north east/above right,
      west/left, center/above, east/right,
      mid west/right, mid/above, mid east/left,
      base west/left, base/below, base east/right,
      south west/below left, south/below, south east/below right,
      text/left, 15/right,150/above}
    \draw[shift=(s.\anchor)] plot[mark=x] coordinates{(0,0)}
      node[\placement,font=\scriptsize] {\texttt{(s.\anchor)}};
  % neue Anker einzeichnen lassen
  \foreach \anchor/\placement in
    {{north 1/3}/above,{north 2/3}/above,{south 1/3}/below,{south 2/3}/below,
      {east 1/3}/right,{east 2/3}/right,{west 1/3}/left,{west 2/3}/left}
    \draw[shift=(s.\anchor),red] plot[mark=x] coordinates{(0,0)}
      node[\placement,font=\scriptsize\bfseries] {\texttt{(s.\anchor)}};
\end{tikzpicture}
\end{document}

Damit kann man dann zum Beispiel folgendes machen (Beispiel aus der Frage auf golatex.de):

Open in writeLaTeX
\begin{tikzpicture}[text width=3em] 
  \node[draw,myrectangle] (test1) {test1\\test1\\test1\\test1}; 
  \draw (test1.east 2/3) -|++(1,1){}; 
  \draw(test1.east 1/3)--
    +(2,0)node[draw,myrectangle,anchor=west 2/3](test2){test2\\test2\\test2}; 
  \draw(test2.west 1/3)-|+(-1,-1); 
\end{tikzpicture}

und erhält

alt text

Permanenter link

beantwortet 25 Jun '14, 18:34

esdd's gravatar image

esdd
14.2k53251

bearbeitet 25 Jun '14, 18:59

Sehr schön! Ich fand noch Martins Ansatz, der wohl mit TikZ 3 laut einem Kommentar nicht mehr so gehen sollte.

(25 Jun '14, 18:54) stefan ♦♦

@Stefan Das sieht interessant aus und wäre besser. Muss man halt mal testen.

(25 Jun '14, 19:11) esdd
Deine Antwort auf die Frage (nicht auf andere Antworten)
Knebel-Vorschau

Folge dieser Frage

Per E-Mail:

Wenn Du Dich anmeldest, kannst Du Updates hier abonnieren

Per RSS:

Antworten

Antworten und Kommentare

Aktuelle Buch-Infos

LaTeX Cookbook

LaTeX Beginners Guide

Limitierter Rabatt ebook
50% Coupon code tDRet6Y

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs füge einfach zwei Leerzeichen an die Stelle ein, an der die neue Zeile sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Zugeordnete Themen:

×492
×108
×51
×8

Frage gestellt: 25 Jun '14, 18:06

Frage wurde angeschaut: 3,087 Mal

Zuletzt aktualisiert: 25 Jun '14, 19:11