相对节点位置

相对节点位置

我正在尝试复制下面显示的非常简单的图形

在此处输入图片描述

以下是我所做的尝试

\documentclass[a4paper]{article}

\usepackage[english]{babel}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}

\usepackage{tikz}

\begin{document}

\begin{figure}[htbp]
    \centering 
\begin{tikzpicture}
  \draw (0,0.1) node[minimum height=0.5cm,minimum width=5cm,draw,color=white] (A2) {};
  \draw (0,0) node[minimum height=1.5cm,minimum width=3cm,draw,align=center] (A1) {Alice \\ $Q = aP$};

  \draw (7,0.1) node[minimum height=0.5cm,minimum width=5cm,draw,color=white] (B2) {};
  \draw (7,0) node[minimum height=1.5cm,minimum width=3cm,draw,align=center] (A1) {Bob \\ $R = bP$};

  \draw[thick,->] (A2.north east) -- (B2.north west) node[above=0.25cm,midway] {P};
  \draw[thick,<-,below] (A2.south east) -- (B2.south west) node[below=0.25cm,midway] {R};
\end{tikzpicture}
\end{figure}
\end{document}

我觉得手动放置节点并隐藏这些白色框非常丑陋。有没有更简洁的方法,使用彼此相关的节点?我尝试使用库matrix,但确切的细节让我困惑。图中的文本当然应该居中(当然不是像现在这样)

答案1

你最好去matrix图书馆tikz

\documentclass[tikz]{standalone}
\usetikzlibrary{matrix}
\newcommand{\mytab}[1]{\begin{tabular}{@{}c@{}} #1\end{tabular}}
\begin{document}
    \begin{tikzpicture}
      \matrix (m) [matrix of nodes,
            nodes={draw,minimum height=1.25cm,minimum width=3cm,draw,align=center},
            column sep=5mm, row sep=15mm, nodes in empty cells]{
        \mytab{Alice \\ $Q = aP$} & |[draw=none]|               & \mytab{Bob \\ $R = bP$}\\
        |[draw=none]|             & \mytab{Charlie \\ $S = cP$} & |[draw=none]|   \\
       };
      \draw[->] ([shift={(1cm,0.25cm)}]m-1-1.east) -- ([shift={(-1cm,0.25cm)}]m-1-3.west) node[midway,above] {Q};
      \draw[<-]([shift={(1cm,-0.25cm)}]m-1-1.east) -- ([shift={(-1cm,-0.25cm)}]m-1-3.west) node[midway,below] {R};
   \draw[->] ([shift={(0.25cm,-0.5cm)}]m-1-1.south) -- ([shift={(-0.5cm,0.25cm)}]m-2-2.west) node[midway,above right] {Q};
      \draw[->] ([shift={(-0.25cm,-0.5cm)}]m-1-1.south) -- ([shift={(-0.5cm,-0.25cm)}]m-2-2.west) node[midway,below left] {S};
    \draw[->] ([shift={(-0.25cm,-0.5cm)}]m-1-3.south) -- ([shift={(0.5cm,0.25cm)}]m-2-2.east) node[midway,above left] {S};
      \draw[->] ([shift={(0.25cm,-0.5cm)}]m-1-3.south) -- ([shift={(0.5cm,-0.25cm)}]m-2-2.east) node[midway,below right] {R};
    \end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

然后您可以使用相对放置选项:)

\documentclass[tikz]{standalone}
\usetikzlibrary{positioning}
\begin{document}
    \begin{tikzpicture}[mystyle/.style={minimum height=1.25cm,minimum width=3cm,
                                        draw,align=center}
                       ]
      \node[mystyle] (A1) {Alice \\ $Q = aP$};
      \node[mystyle,right=5cm of A1] (A2) {Bob \\ $R = bP$};

      \draw[->,shorten <=1cm,shorten >=1cm] 
            ([yshift=0.25cm]A1.east) -- ([yshift=0.25cm]A2.west) node[midway,above] {Q};
      \draw[<-,shorten <=1cm,shorten >=1cm] 
            ([yshift=-0.25cm]A1.east) -- ([yshift=-0.25cm]A2.west) node[midway,below] {R};
    \end{tikzpicture}
\end{document}

答案3

对于可能感兴趣的人,这里有一种使用 MetaPost 和boxes包来实现此目的的方法,为了方便起见,包含在 LuaLaTeX 程序中。

框的位置由以下线条隐式确定

b.w = origin - a.e = a.e + (3cm, 0);

这告诉 MetaPost 它们必须围绕水平 x 轴上的原点对称放置,并且框的侧边框必须相距 3 厘米。

参数hgapvgap分别表示箭头与框之间的水平间隙,以及两个箭头之间的垂直间隙。

\documentclass[border=2mm]{standalone}
\usepackage{luamplib}
    \mplibsetformat{metafun}
\begin{document}
  \begin{mplibcode}
    input boxes;
    hgap := .5cm; vgap = 3mm; 
    beginfig(1);
      boxit.a(btex \begin{tabular}{c} Alice \\ $Q = aP$ \end{tabular} etex);
      boxit.b(btex \begin{tabular}{c} Bob \\ $R = bP$ \end{tabular} etex);
      b.w = origin - a.e = a.e + (3cm, 0);
      path join[]; 
      join1 = (a.e -- b.w) shortened hgap yshifted .5vgap;
      join2 = reverse join1 yshifted -vgap;
      drawboxed(a, b); drawarrow join1; drawarrow join2;
      label.top(btex $Q$ etex, point .5 of join1);
      label.bot(btex $R$ etex, point .5 of join2);
    endfig;
  \end{mplibcode}
\end{document}

输出:

在此处输入图片描述

编辑现在来看看 Percusse 的答案评论中要求的三个框。我分别将hgap和的名称改为和,但它们的作用没有改变。对于第三个框,我认为最好将其明确放置。vgapboxgaparr_gap

\documentclass[border=2mm]{standalone}
\usepackage{luamplib}
    \mplibsetformat{metafun}
\begin{document}
  \begin{mplibcode}
    input boxes;
    path join.ab, join.ba, join.bc, join.cb, join.ac, join.ca; 
    beginfig(1);
      boxit.a(btex \begin{tabular}{c} Alice \\ $Q = aP$ \end{tabular} etex);
      boxit.b(btex \begin{tabular}{c} Bob \\ $R = bP$ \end{tabular} etex);
      boxit.c(btex \begin{tabular}{c} Charlie \\ $S = cP$ \end{tabular} etex);

      b.w = origin - a.e = a.e + (4cm, 0); c.n = (0, -2cm);

      boxgap := 5mm; arr_gap := 3mm;
      join.ab = (a.e -- b.w) shortened boxgap yshifted .5arr_gap;
      join.ba = reverse join.ab yshifted -arr_gap;
      drawboxed(a, b, c); drawarrow join.ab; drawarrow join.ba;
      label.top(btex $Q$ etex, point .5 of join.ab);
      label.bot(btex $R$ etex, point .5 of join.ba);

      arr_gap := 4.5mm;
      join.bc = (b.s xshifted arr_gap -- c.e yshifted -arr_gap) shortened boxgap;
      join.cb = (c.e --  b.s) shortened boxgap;
      drawarrow join.bc; drawarrow join.cb;
      label.lrt(btex $R$ etex, point .5 of join.bc);
      label.ulft(btex $S$ etex, point .5 of join.cb);

      join.ac = (a.s -- c.w) shortened boxgap;
      join.ca = (c.w yshifted -arr_gap --  a.s xshifted -arr_gap) shortened boxgap;
      drawarrow join.ac; drawarrow join.ca;
      label.urt(btex $Q$ etex, point .5 of join.ac);
      label.llft(btex $S$ etex, point .5 of join.ca);
    endfig;
  \end{mplibcode}
\end{document}

在此处输入图片描述

答案4

这是使用 cryptocode 包实现上述目的的另一种方法(https://www.ctan.org/pkg/cryptocode)。

编写协议的加密方式更适合以下风格

在此处输入图片描述

其生成方式为:

\documentclass{article}

\usepackage{cryptocode}

\begin{document}

\pseudocode{
\textbf{Alice} \< \< \textbf{Bob} \\
Q =aP  \< \< \\
\< \sendmessageright{top=$Q$} \<   \\
\< \< R=bP \\
\< \sendmessageleft{top=$R$} \< }

\end{document}

这个想法是,双人协议可以通过 3 列可视化,左列显示第一个玩家的动作,第三列显示第二个玩家的动作,而中间列包含正在交换的消息。切换列是通过 '\<' 完成的。但是,您也可以在命令中混合使用 tikz \pseudocode(使用\pcdraw)来获取原始图片:

\documentclass{article}

\usepackage{cryptocode}

\begin{document}

\pseudocode{
\pcdraw{ 
  \node[yshift=-0.35cm,draw,minimum height=0.5cm,minimum width=2cm] {\tikz{
     \node (alice) {Alice}; 
     \node[below=0.1cm of alice] {$Q=aP$};
   }};
}\phantom{AliceB } \< \sendmessageright{length=2cm,top=$Q$} \< 
\phantom{Bob }\pcdraw{
  \node[yshift=-0.35cm,draw,minimum height=0.5cm,minimum width=2cm] {\tikz {
    \node (bob) {Bob}; 
    \node[below=0.1cm of bob] {$R=bP$};
  }};
}  \\
\< \sendmessageleft{length=2cm,bottom=$R$} \< 
}

\end{document}

在此处输入图片描述

这里是三人解决方案,尽管这可能现在有点延伸了这个包的目的......

\documentclass{article}

\usepackage{cryptocode}

\begin{document}

\begin{pcimage}
\pseudocode{
\pcdraw{ 
  \node[yshift=-0.35cm,outer sep=0.1cm,draw,minimum height=0.5cm,minimum width=2cm](alicebox) {\tikz{
     \node (alice) {Alice}; 
     \node[below=0.1cm of alice] {$Q=aP$};
   }};
}\phantom{AliceB } \< \sendmessageright{length=2cm,top=$Q$} \< 
\phantom{Bob }\pcdraw{
  \node[yshift=-0.35cm,outer sep=0.1cm,draw,minimum height=0.5cm,minimum width=2cm] (bobbox) {\tikz {
    \node (bob) {Bob}; 
    \node[below=0.1cm of bob] {$R=bP$};
  }};
}  \\
\< \sendmessageleft{length=2cm,bottom=$R$,bottomname=bobsmsg} \< \\[1cm]
\< \pcdraw{
 \node[below=of bobsmsg,outer sep=0.1cm,draw,minimum height=0.5cm,minimum width=2cm] (charliebox) {\tikz {
    \node (charlie) {Charlie}; 
    \node[below=0.1cm of charlie] {$S=cP$};
   }};
%communication with alice
   \draw[->] (charliebox.north west) -- node[right=0.25cm] {$Q$} (alicebox);
   \draw[->] (alicebox.south) -- node[left=0.25cm] {$S$} (charliebox.west);
%communication with bob
   \draw[->] (charliebox.north east) -- node[left=0.25cm] {$Q$} (bobbox);
   \draw[->] (bobbox.south) -- node[right=0.25cm] {$R$} (charliebox.east);
} \<
}
\end{pcimage}

\end{document}

在此处输入图片描述

相关内容