我正在尝试复制下面显示的非常简单的图形
以下是我所做的尝试
\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 厘米。
参数hgap
和vgap
分别表示箭头与框之间的水平间隙,以及两个箭头之间的垂直间隙。
\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
和的名称改为和,但它们的作用没有改变。对于第三个框,我认为最好将其明确放置。vgap
boxgap
arr_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}