为了对齐,我试图在同一个 tikz 图片中绘制两个相关的精确序列。我目前已将 tikzpicture 环境包装在方程环境中,以便两者具有相同的数字。理想情况下,我希望有单独的方程编号;有办法做到这一点吗?
\documentclass{amsart}
\usepackage{tikz}
\usetikzlibrary{matrix,arrows}
\newcommand\Z[2]{\ensuremath{\mathfrak Z^{(#1)}_{#2}}}
\begin{document}
\begin{equation}
\begin{tikzpicture}
[description/.style={fill=white,inner sep=2pt},baseline=(current bounding box.center)]
\matrix (m) [matrix of math nodes, row sep=1em, column sep=1.5em, text height=1.5ex, text depth=0.25ex]
{
0 & \Omega^k_X & \Z k k & \Z k {k-1} & \cdots & \Z k 1 & \Z k 0 & 0\phantom .\\
0 & \Lambda^k \mathcal E^\vee & \Z k k & \Z k {k-1} & \cdots & \Z k 1 & \Z k 0 & 0.\\
};
\foreach \a in {2,3,...,8} {
\pgfmathsubtract{\a}{1}
\draw[->] (m-1-\pgfmathresult) -- (m-1-\a);
\draw[->] (m-2-\pgfmathresult) -- (m-2-\a);
};
\end{tikzpicture}
\end{equation}
\end{document}
答案1
我猜想有两种方法可以做到这一点。要么有两个编号的方程式(可能在环境中align
),每个方程式都有自己的tikzpicture
,并尝试对齐 s 的相关部分tikzpicture
,要么模拟 内的方程式编号tikzpicture
。我在这里选择了后一种方法。
首先是结果。前两行是环境中的原始正合序列equation
。后两行是我在 中嵌入方程编号的地方tikzpicture
。
现在代码:
\documentclass{amsart}
\thispagestyle{empty}
\usepackage{tikz}
\usetikzlibrary{matrix,arrows}
\newcommand\Z[2]{\ensuremath{\mathfrak Z^{(#1)}_{#2}}}
% labeling, we assume that we are centred on the line
\makeatletter
\newlength{\tikz@label@eqnlen}
\newcommand{\tikzlabel}[2][]{%
\pgfgetlastxy{\tikz@label@x}{\tikz@label@y}%
\path (current bounding box.north east);
\pgfgetlastxy{\tikz@label@nex}{\tikz@label@ney}%
\path (current bounding box.north west);
\pgfgetlastxy{\tikz@label@nwx}{\tikz@label@nwy}%
\pgfmathsetlength{\tikz@label@eqnlen}{(\textwidth - (\tikz@label@nex - \tikz@label@nwx))/2 - (\tikz@label@nwx - \tikz@label@x)}
\begin{pgfinterruptboundingbox}
\path (\tikz@label@x,\tikz@label@y) ++(-\tikz@label@eqnlen,0) node[anchor=west,inner sep=0pt,#1] {\refstepcounter{equation}(\theequation)};
\end{pgfinterruptboundingbox}
\def\@currentlabel{\theequation}
\ltx@label{#2}}
}
\makeatother
\begin{document}
\begin{equation}
\label{eq:orig}
\begin{tikzpicture}
[baseline=(current bounding box.center)]
\matrix (m) [matrix of math nodes, row sep=1em, column sep=1.5em, text height=1.5ex, text depth=0.25ex]
{
0 & \Omega^k_X & \Z k k & \Z k {k-1} & \cdots & \Z k 1 & \Z k 0 & 0\phantom .\\
0 & \Lambda^k \mathcal E^\vee & \Z k k & \Z k {k-1} & \cdots & \Z k 1 & \Z k 0 & 0.\\
};
\foreach \a in {2,3,...,8} {
\pgfmathsubtract{\a}{1}
\draw[->] (m-1-\pgfmathresult) -- (m-1-\a);
\draw[->] (m-2-\pgfmathresult) -- (m-2-\a);
};
\end{tikzpicture}
\end{equation}
\begin{equation*}
\begin{tikzpicture}
[baseline=(current bounding box.center)]
\matrix (m) [matrix of math nodes, row sep=1em, column sep=1.5em, text height=1.5ex, text depth=0.25ex]
{
0 & \Omega^k_X & \Z k k & \Z k {k-1} & \cdots & \Z k 1 & \Z k 0 & 0\phantom .\\
0 & \Lambda^k \mathcal E^\vee & \Z k k & \Z k {k-1} & \cdots & \Z k 1 & \Z k 0 & 0.\\
};
\foreach \a in {2,3,...,8} {
\pgfmathsubtract{\a}{1}
\draw[->] (m-1-\pgfmathresult) -- (m-1-\a);
\draw[->] (m-2-\pgfmathresult) -- (m-2-\a);
};
\foreach \b in {1,2} {
\path (m-\b-1.west);
\tikzlabel{eq:se\b}
}
\end{tikzpicture}
\end{equation*}
Let's refer to \eqref{eq:se1} and \eqref{eq:se2}; but not to \eqref{eq:orig}.
\end{document}
复杂之处在于计算方程编号的放置位置。我们测量当前边界框以获取宽度,然后从文本宽度中减去该宽度,再除以二。这样我们就得到了边界框到左边距的距离(因为方程将居中)。但是,我们需要从矩阵中最左边节点的边缘开始计算(以获得正确的高度),而这不一定是在边界框的边缘。所以我们对此进行了修正。因此,我们可以将左边距定位在正确的高度,并将方程编号放在我们想要的位置。另一个神奇之处是pgfinterruptboundingbox
(我从杰克那里学到的一个技巧)从边界框计算中删除方程编号,从而确保精确的序列保持居中。
编辑中添加:我添加了标签功能,并将其重构为单独的命令。语法是,\tikzlabel[node options]{label}
将在最后一个点所在的级别左边距添加一个方程编号,并设置label
为指向它(以便\ref{label}
或\eqref{label}
正常工作)。因此,在这个例子中,我们(m-\b-1.west)
在调用它之前“使用”该点。(另一种方法是将该点提供给命令\tikzlabel
。)可选的node options
get 添加到放置标签的节点。因此,可以为标签着色、重新定位(例如,如果垂直对齐不太正确)或执行任何其他操作。默认使用带有west
的锚点inner sep=0pt
,但任何额外选项都放在最后,因此可以覆盖这些选项。
最好最后放置标签,因为我们必须根据边界框猜测左边距在哪里,并且只能知道当前状态下的边界框(我曾在某处看到过将代码放在图片末尾的东西,这是一个很好的用途,但我自己还没有用过,所以我需要进行实验才能做到正确)。