Hallo zusammen,

ich habe zwei Matrizen erstellt, die unterschiedlich viele Elemente enthalen (3 in der linken Matrix und 5 in der rechten Matrix). Die Größen und die row seperation habe ich jedoch so gewählt, dass die beiden Matrizen theoretisch gleich hoch sein sollten, nämlich 7 cm. 7 cm ergeben sich bei der linken Matrix aus der Höhe der Elemente + der Höhe der Abstände zwischen den Elementen = 1cm + 0,5cm + 1cm +0,5cm + 4cm. Analog bei der rechten Matrix: 1 cm + 0,5 cm + 1 cm + 0,5 cm + 1 cm + 0,5 cm + 1 cm + 0,5 cm + 1 cm = 7 cm. So sollte es sein, ist es jedoch nicht. Die rechte Matrix ist ein kleines Stück größer, weil sie mehr Elemente enthält und zu jedem Element scheinbar ein zusätzlicher kleiner Abstand addiert wird. Dies lässt sich, wenn man genau hinsieht am Grid erkennen, aber bspw. auch an dem nicht perfekt horizontalen Pfeil von "mit. Elem. 5" zu "rechtes Element 5". Auch die linke Matrix ist nicht exakt 7 cm hoch, sondern 7 cm + x. Wie lässt sich diese Ungenauigkeit erklären und vorallem verhindern, sodass beide Matrizen genau 7 cm hoch sind?

Hier das MB. Vielen Dank schonmal.

    \documentclass{scrbook}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern} 
\usepackage[ngerman]{babel}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{calc}
\tikzset{
*|/.style={to path={(\tikztostart-|\tikztotarget) -- (\tikztotarget) \tikztonodes}},
*-/.style={to path={(\tikztostart|-\tikztotarget) -- (\tikztotarget) \tikztonodes}}}

\begin{document}
\begin{tikzpicture}[
reklein/.style={rectangle,draw,minimum width=4cm,minimum height=1cm,anchor=north west,align=center},
rerund/.style={rectangle,draw,minimum width=3cm,anchor=center,align=center},
pfeil/.style={semithick,->,shorten >=5pt,shorten <=5pt}]

% Grid
    \draw[step=0.5cm,very thin,gray] (0,0) grid(14,20);

% linke Matrix  
    \matrix(mat)[row sep=5mm,column sep=5cm,anchor=north west,inner sep=0mm] at (0,14){
    \node [reklein](prod1) {linkes Element 1};\\
    \node [reklein](prod2) {linkes Element 2};\\
    \node [reklein,minimum height=4cm](prod3) {linkes Element 3};   \\
    };

% rechte Matrix 
    \matrix(mat)[row sep=5mm,column sep=5cm,anchor=north east,inner sep=0mm] at (14,14){
    \node [reklein](prod4) {rechtes Element 1};\\
    \node [reklein](prod5) {rechtes Element 2};\\
    \node [reklein](prod6) {rechtes Element 3};\\
    \node [reklein](prod7) {rechtes Element 4};\\
    \node [reklein](prod8) {rechtes Element 5};\\
    };

% mittlere Elemente 
    \node [rerund] (rund1) at ($0.5*(prod1)+0.5*(prod4)$) {mit. Elem. 1};
    \node [rerund] (rund2) at ($0.5*(prod2)+0.5*(prod5)$) {mit. Elem. 2};
    \node [rerund] (rund3) at ($(rund2)-(0,1.5)$) {mit. Elem. 3};
    \node [rerund] (rund4) at ($0.5*(prod3)+0.5*(prod7)$) {mit. Elem. 4};
    \node [rerund] (rund5) at ($(rund4)-(0,1.5)$) {mit. Elem. 5};

% Verbindungen über Pfeile
    \draw [pfeil] (rund1) to (prod1);
    \draw [pfeil] (rund1) to (prod4);
    \draw [pfeil] (rund2) to (prod2);
    \draw [pfeil] (rund2) to (prod5);
    \draw [pfeil] (rund3.west) to (prod3);
    \draw [pfeil] (rund3) to (prod6);
    \draw [pfeil] (rund4) to (prod3);
    \draw [pfeil] (rund4) to (prod7);
    \draw [pfeil] (rund5.west) to (prod3);
    \draw [pfeil] (rund5) to (prod8);

\end{tikzpicture}
\end{document}

gefragt 13 Aug '13, 10:32

josephine's gravatar image

josephine
944253035
Akzeptiert-Rate: 0%

bearbeitet 19 Aug '13, 10:39

cgnieder's gravatar image

cgnieder
22.1k253463

Wenn du row sep=0mm setzt, kann man etwas besser sehen, was passiert. Die Linien der Nodes überlappen dann nämlich nicht. Dazu muss der Abstand zwischen den Zeilen -\pgflinewidth sein. (Die minimum height bezieht sich nur auf die Pfadlinienmitte, es wird somit .5\pgflinewidth von der unteren Kante der oberen Node und .5\pgflinewidth der oberen Kante der unteren Node abgezogen.) Ähnliches passiert auch nach außen hin, weswegen die Nodes in den Matrizen nicht perfekt am Grid orientiert sind, was mit inner sep=-.5\pgflinewidth (Matrix-Option) verhindern werden kann.

(13 Aug '13, 10:51) Qrrbrbirlbel

Man erkennt am besten, was passiert, wenn man die Liniendicke hoch setzt und den Zeilenabstand auf Null.

Die Matrix selbst ist in blau gezeichnet, die Nodes in schwarz. Die Option opacity=.5 hilft hier, zu sehen, wo was liegt.

alt text

Die Werte minimum width und minimum height bezeichnen nur die Dimensionen ohne der Dicke der Linie (ähnlicher Grund, warum es outer seps gibt). Die Zellen selbst orientieren sich aber nicht an den Pfaden, sondern bekommen alle eine eigene Bounding Box, die eben auch die Dicke der Linien beachtet (normalerweise ist das so gewünscht).

Wir müssen also \pgflinewidth von dem row sep abziehen.

Dazu kommt aber noch ein Faktor, warum die Nodes nicht perfekt auf dem Grid liegen.

Die Matrix selbst beachtet ebenfalls eine outer sep-Einstellung, was dazu führt, dass der Außenrand der Linie der Matrix (die in deinem Fall ja nichtmal gezeichnet ist) die Anchors bekommt. (Normalerweise ist das auch so gewünscht, damit Linien und Pfeile die Nodes nur berühren.)

Es genügt also die Matrix auf outer sep=+0pt zu setzen. Dann liegen aber die Pfade der Nodes immer noch nicht aufm Grid, denn auch das innere Padding (also nicht zwischen den Nodes, sondern zwischen den Nodes und der Matrix) muss noch eliminiert werden. Wir setzen also auch den inner sep der Matrix auf -.5\pgflinewidth.

Der Style tight matrix of nodes macht genau, wobei die Einstellung zu den seps vorher an den Anfang des every node-Styles gespeichert werden; an den Anfang deshalb um keine anderen Einstellungen, die vorher in dem every node-Style gespeichert sind zu überschreiben.

Die matrix-Library liefert den matrix of nodes-Style, der außerdem die Nodes noch automatsch benennt: <matrix-name>-<Zeile>-<Spalte>.

Diese Namen sind dann verwendet um die mittleren Nodes zu positionieren und die Linien zu bezeichnen.

Ich verwende dafür den *--to path von meiner Antwort zu deiner Frage über rein vertikale/horizontale Linien

Code

\documentclass[tikz,convert=false]{standalone}
\usetikzlibrary{matrix,backgrounds}
\tikzset{
  tight matrix of nodes/.style={
    matrix of nodes,% kommt von der matrix-Library
    every node/.prefix style/.expanded={% wir speichern die aktuelle Werte in dem every-node-Style ab
      inner xsep={\pgfkeysvalueof{/pgf/inner xsep}},
      inner ysep={\pgfkeysvalueof{/pgf/inner ysep}},
      outer xsep={\pgfkeysvalueof{/pgf/outer xsep}},
      outer ysep={\pgfkeysvalueof{/pgf/outer ysep}},
    },
    % und überschreiben dann die Werte extra für die Matrix
    inner sep=+-.5\pgflinewidth,
    outer sep=+0pt
  }
}
\makeatletter
\newif\iftikz@ortho@preflush
\tikz@ortho@preflushtrue
\let\tikz@origtotarget\pgfutil@empty
\tikzset{
  *-/.style={to path={%
    \pgfextra
      \iftikz@shapeborder
        \tikz@scan@one@point\pgfutil@firstofone(\tikztotarget)\relax
        \ifdim\pgf@x>\tikz@lastx\relax
          \edef\tikztostart{\tikztostart.east}%
        \else
          \edef\tikztostart{\tikztostart.west}%
        \fi
      \fi
    \endpgfextra
    (\tikztostart|-\tikztotarget) -- (\tikztotarget) \tikztonodes
  }},
  node as new start/.is if=tikz@ortho@preflush
}
\makeatother
\begin{document}
\begin{tikzpicture}[
  gridded,
  every matrix node/.style={
    shape=rectangle,
    draw=black,
    minimum width=+4cm,
    minimum height=+1cm,
    align=center},
  every other node/.style={
    shape=rectangle,
    draw,
    minimum width=+3cm,
    align=center,
    anchor=center}
]
  \matrix (mat1) [
    tight matrix of nodes,
    nodes=every matrix node,
    row sep=5mm-\pgflinewidth,
    matrix anchor=north west] at (0,14) {
    linkes Element 1                        \\
    linkes Element 2                        \\
    |[minimum height=4cm]| linkes Element 3 \\
  };
  \matrix (mat2) [
    tight matrix of nodes,
    nodes=every matrix node,
    row sep=5mm-\pgflinewidth,
    matrix anchor=north east] at (14,14) {
    rechtes Element 1 \\
    rechtes Element 2 \\
    rechtes Element 3 \\
    rechtes Element 4 \\
    rechtes Element 5 \\
  };

  \foreach \reiheLinks/\reiheRechts[count=\cIndex] in {1/1, 2/2, 3/3, 3/4, 3/5} {
    \path (mat1-\reiheLinks-1) to[*-]  node[every other node] (rund\cIndex) {mit. Elem. \cIndex} (mat2-\reiheRechts-1);
    \path[->,semithick,shorten >=5pt,shorten <=5pt] (rund\cIndex)      edge (mat2-\reiheRechts-1) 
                                                    (rund\cIndex.west) edge (mat1-\reiheLinks-1);
  }
\end{tikzpicture}
\end{document}

Resultat

alt text

Permanenter link

beantwortet 19 Aug '13, 04:09

Qrrbrbirlbel's gravatar image

Qrrbrbirlbel
2.9k3815
Akzeptiert-Rate: 53%

@Qrrbrbirlbel Danke für die Hilfe. Dein Kommentar hat mir auf jeden Fall sehr geholfen. Ich musste allerdings noch eine kleinere weitere Anpassung vornehmen, damit es auch 100 %ig funktioniert. Das Problem liegt ja nicht nur bei der inner sep der Matrix, sondern auch beim Abstand zwischen den Zeilen der Matrix. Dieser muss demnach auch nochmal um die Hälfte der Linienstärke des oberen und um die Hälfte der Linienstärke des unteren Elements angepasst werden, also um -2 mal 0,5 mal pgflinewidth=-1 pgflinewidth. Unten nun meine Lösung:

    \documentclass{scrbook}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern} 
\usepackage[ngerman]{babel}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}[
reklein/.style={rectangle,draw,minimum width=4cm,minimum height=1cm,anchor=north west,align=center},
rerund/.style={rectangle,draw,minimum width=3cm,anchor=center,align=center},
pfeil/.style={semithick,->,shorten >=5pt,shorten <=5pt}]

% Grid
    \draw[step=0.5cm,very thin,gray] (0,0) grid(14,20);

% linke Matrix  
    \matrix(mat)[row sep=5mm-1\pgflinewidth,column sep=5cm,anchor=north west,inner sep=-0.5\pgflinewidth] at (0,14){
    \node [reklein](prod1) {linkes Element 1};\\
    \node [reklein](prod2) {linkes Element 2};\\
    \node [reklein,minimum height=4cm](prod3) {linkes Element 3};   \\
    };

% rechte Matrix 
    \matrix(mat)[row sep=5mm-1\pgflinewidth,column sep=5cm,anchor=north east,inner sep=-0.5\pgflinewidth] at (14,14){
    \node [reklein](prod4) {rechtes Element 1};\\
    \node [reklein](prod5) {rechtes Element 2};\\
    \node [reklein](prod6) {rechtes Element 3};\\
    \node [reklein](prod7) {rechtes Element 4};\\
    \node [reklein](prod8) {rechtes Element 5};\\
    };

% mittlere Elemente 
    \node [rerund] (rund1) at ($0.5*(prod1)+0.5*(prod4)$) {mit. Elem. 1};
    \node [rerund] (rund2) at ($0.5*(prod2)+0.5*(prod5)$) {mit. Elem. 2};
    \node [rerund] (rund3) at ($(rund2)-(0,1.5)$) {mit. Elem. 3};
    \node [rerund] (rund4) at ($0.5*(prod3)+0.5*(prod7)$) {mit. Elem. 4};
    \node [rerund] (rund5) at ($(rund4)-(0,1.5)$) {mit. Elem. 5};

% Verbindungen über Pfeile
    \draw [pfeil] (rund1) to (prod1);
    \draw [pfeil] (rund1) to (prod4);
    \draw [pfeil] (rund2) to (prod2);
    \draw [pfeil] (rund2) to (prod5);
    \draw [pfeil] (rund3.west) to (prod3);
    \draw [pfeil] (rund3) to (prod6);
    \draw [pfeil] (rund4) to (prod3);
    \draw [pfeil] (rund4) to (prod7);
    \draw [pfeil] (rund5.west) to (prod3);
    \draw [pfeil] (rund5) to (prod8);

\end{tikzpicture}
\end{document}
Permanenter link

beantwortet 13 Aug '13, 11:46

josephine's gravatar image

josephine
944253035
Akzeptiert-Rate: 0%

bearbeitet 13 Aug '13, 11:48

Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

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ügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×730
×69
×58

gestellte Frage: 13 Aug '13, 10:32

Frage wurde gesehen: 13,158 Mal

zuletzt geändert: 19 Aug '13, 10:39