Re: Tikz: rendere omogenea la linea di base e altri quesiti

#63641
admin
Amministratore del forum
    Up
    0
    Down
    ::

    antonio.macrì” post=62607Ciao a tutti!

    Oggi ho iniziato a smanettare con TikZ in previsione di farci qualcosa di serio. Ho provato a scrivere un diagramma, ma non riesco a rendere omogenea la linea di base di alcune scritte. Questo è il codice:
    `
    \documentclass{standalone}

    \usepackage[T1]{fontenc}
    \usepackage[utf8]{inputenc}
    \usepackage[italian]{babel}
    \usepackage{tikz}

    % TikZ
    \usetikzlibrary{shapes,arrows,chains,calc,positioning}
    \tikzstyle{block} = [draw, fill=blue!20, minimum height=2em, rectangle]
    \tikzstyle{point} = [circle, inner sep=0pt]%, fill=red, minimum width=2pt]
    \newcommand\DeclareText[2]{%
    \expandafter\newskip\csname#1width\endcsname%
    \expandafter\settowidth\csname#1width\endcsname{#2}%
    \expandafter\addtolength\csname#1width\endcsname{1.5em}%
    }
    \newskip\NodeDistance
    \NodeDistance=2.5em
    \newskip\HalfNodeDistance
    \HalfNodeDistance=\NodeDistance
    \divide\HalfNodeDistance by 2

    \makeatletter
    \newcommand\acs{\@ifstar{\textsc}{\textsc}}
    \makeatother

    \begin{document}

    \centering
    {\small
    \DeclareText{seed}{Seed}
    \DeclareText{ks}{stream}
    \DeclareText{key}{\acs*{WEP} key}
    \begin{tikzpicture}[anchor=base, >=latex']
    \node [block, minimum height=4em] (xor) {$\oplus$};
    \node [point] at ($(xor.south west)!.75!(xor.north west)$) (ks-anchor) {};
    \node [point] at ($(xor.south west)!.25!(xor.north west)$) (p-anchor) {};

    \node [block, left=\kswidth of ks-anchor] (prng) {RC4 \acs*{PRNG}};
    \node [block, minimum height=4em, left=\seedwidth of prng.west] (concat-a) {$\langle\cdot,\cdot\rangle$};
    \node [point] at ($(concat-a.south west)!.75!(concat-a.north west)$) (iv-anchor) {};
    \node [point] at ($(concat-a.south west)!.25!(concat-a.north west)$) (key-anchor) {};
    \node (iv) [point, left=\keywidth of iv-anchor] {};
    \node (key) [point, left=\keywidth of key-anchor] {};

    \node [block, minimum height=4em, anchor=east] at ($(p-anchor.west)-(\kswidth,2em)$) (concat-b) {$\langle\cdot,\cdot\rangle$};
    \node [point] at ($(concat-b.south west)!.75!(concat-b.north west)$) (m-anchor) {};
    \node [point] at ($(concat-b.south west)!.25!(concat-b.north west)$) (icv-anchor) {};

    \node (crc) [block, anchor=west] at (icv-anchor -| concat-a.west) {CRC-32};
    \node (message) [point] at (key |- m-anchor) {};

    \node (ciphertext) [block, anchor=west, minimum height=8em, minimum width=7em] at ($(xor.south)+(\NodeDistance,1em)$) {Cipher text};
    \node [block, above=0.1em of ciphertext, minimum width=7em] (ivout) {\acs*{IV}};

    \node [point] at ($(message)+(\the\dimexpr\keywidth/2\relax,0)$) (under-message) {};
    \node [above=0pt of under-message, anchor=base, yshift=0.35em] (m) {Message};

    \draw [->] (iv) — node[yshift=0.35em] {\acs*{IV}} (iv-anchor);
    \draw [->] (key) — node[yshift=0.35em] {\acs*{WEP} key} (key-anchor);
    \draw [->] (concat-a) — node[yshift=0.35em] {Seed} (prng);
    \draw [->] (concat-b.east) -| ($(p-anchor.east)-(\the\dimexpr\kswidth/2\relax,0)$) — (p-anchor);
    \draw [->, text width=4em, align=center] (prng) — node[yshift=0.35em] {Key stream} (ks-anchor);
    \draw [->] (crc) — node[yshift=0.35em] {\acs*{ICV}} (icv-anchor);
    \draw [->] (message) — (m-anchor);
    \draw [->] (under-message.center) |- (crc.west);
    \draw [->] (xor) — (ciphertext.west |- xor.east);
    \draw [->] ($(iv)+(4em,0)$) |- (ivout.west);
    \end{tikzpicture}}
    \end{document}`
    Mi riferisco ad esempio alla distanza della linea di base delle scritte “IV”, “WEP key” e “Message” dalla rispettiva freccia orizzontale. Ho provato, come primo tentativo, ad imporre (anchor=base), e questo funziona per IV e WEP key (ma non per Message). Ho però dovuto aggiungere uno scostamento verticale (yshift=0.35em), per evitare che i discendenti si sovrapponessero alla freccia. Due domande:

    • Esiste un modo migliore per allineare le linee di base senza avere sovrapposizione? Vorrei evitare di specificare lo scostamento verticale per ogni etichetta.
    • Come faccio a rendere uguale anche la distanza della linea di base dell’etichetta “Message” (ovvero del nodo m)? Non funziona né imponendo anchor=baseanchor=center.

    E dato che è la prima volta che mi ci metto, chiedo consigli generali:

    • Imposto la dimensione delle frecce al minimo, ovvero alla larghezza del testo dell’etichetta calcolata con \settowidth. TikZ fornisce un modo di più alto livello per farlo? Vorrei non dover richiamare TeX.
    • TikZ consente di specificare con grande precisione la posizione di un oggetto (mediante at ($(…)+(…)$) e simili). Vorrei invece specificare in dettaglio l’ancora dell’oggetto, ovvero qualcosa come anchor=<1em al di sotto di north west>. È possibile?

    Grazie dell’aiuto e dei consigli,
    Antonio

    Forse la risposta arriva fuori tempo massimo: vedi se la discussione Problem with TikZ and vertical alignment of text inside nodes può esserti di aiuto.

    Ciao
    Orlando

    Go to top