
我正在使用解決方案形式透過數學節點的 TiKZ 矩陣模擬 amsmath 矩陣的障礙tikz
matrix
以 a 的風格創建bmatrix
.這工作得很好,預設規格為
every delimiter/.style={yshift=-1pt}.
但是,有時候我想手動分別調整左/右分隔符號的頂部和左/右分隔符號的底部,因此嘗試找到一種tikz
方法來做到這一點。我可以駭客透過放置phantom
垂直線來實現,但如果有 tikz 樣式會更好。理想情況下,解決方案應具有如下所示的樣式:
left delimiter top y shift=
left delimiter bottom y shift=
right delimiter top y shift=
right delimiter bottom y shift=
對於頂部和底部分隔符號的關聯分隔符號也類似(此處未使用)
top delimiter left x shift=
top delimiter right x shift=
bottom delimiter left x shift=
bottom delimiter right x shift=
需要明確的是,我並不期待自動化解決方案,而是根據需要手動調整分隔符號。
下面是一個做作的範例(令我驚訝的是,bmatrix
預設會產生所需的結果,但不明白如何),兩種情況的矩陣的第一行是
\smash{1} & \smash{4} \\
代碼:
\documentclass{article}
\usepackage{mathtools}% for amsmath {bmatrix}
\usepackage{tikz}
\usetikzlibrary{matrix}
%% https://tex.stackexchange.com/questions/26866/obstacles-to-simulating-an-amsmath-matrix-by-a-tikz-matrix-of-math-nodes
\newlength\mtxrowsep \setlength\mtxrowsep{1.5ex}
\newlength\mtxcolsep \setlength\mtxcolsep{2\arraycolsep}
\tikzset{
ams/.style={
baseline=-.7ex,
every delimiter/.style={yshift=-1pt},
every left delimiter/.style={xshift=2pt},
every right delimiter/.style={xshift=-2pt},
every node/.style={inner sep=0pt},
},
ams matrix/.style={
inner sep=1pt,
column sep=\mtxcolsep,
row sep=\mtxrowsep,
% Following is also commented at https://tex.stackexchange.com/questions/26866
%ampersand replacement=\&,
matrix of math nodes,
},
bmatrix/.style={
ams,
every matrix/.style={
ams matrix,
left delimiter={[},
right delimiter={]},
}
},
Bmatrix/.style={
ams,
every matrix/.style={
ams matrix,
left delimiter={\lbrace},
right delimiter={\rbrace},
}
},
pmatrix/.style={
ams,
every matrix/.style={
ams matrix,
left delimiter={(},
right delimiter={)},
}
},
vmatrix/.style={
ams,
every matrix/.style={
ams matrix,
left delimiter={|},
right delimiter={|},
}
},
Vmatrix/.style={
ams,
every matrix/.style={
ams matrix,
left delimiter={\|},
right delimiter={\|},
}
},
}
%% This does not seem to be necessary
%\let\matamp=&
%
%\catcode`\&=13
%\makeatletter
%\def&{\iftikz@is@matrix
% \pgfmatrixnextcell
% \else
% \matamp
% \fi}
%\makeatother
\begin{document}
\hspace*{0.2em}
\begin{tikzpicture}[bmatrix]
\matrix (m) {
\smash{1} & \smash{4} \\
7 & 10 \\
13 & 16 \\
};
\end{tikzpicture}
%% ----------------
\hspace*{0.3em}
$\begin{bmatrix}
\smash{1} & \smash{4} \\
7 & 10 \\
13 & 16 \\
\end{bmatrix}$
tikz matrix \hspace*{0.6em} bmatrix
\end{document}
答案1
我只能使用兩個額外的鍵來重新實作分隔符號:delim' top
和delim' bot
。
不知道不對稱方法(左右以及上下具有不同的值)是否是一個好主意,或者只是讓它變得有點複雜...
程式碼
\documentclass{article}
\usepackage{mathtools}% for amsmath {bmatrix}
\usepackage{tikz}
\usetikzlibrary{matrix}
\tikzset{% similar to axis_height of TikZ-CD
vcenter/.code=\begingroup$\relax$\pgfmathreturn
\the\fontdimen22\textfont2\endgroup
\pgfsetbaseline{-\pgfmathresult pt}}
\tikzset{
delimiter' top/.code=\pgfmathparse{#1}% self-evaluating
\pgfkeyssetevalue{/tikz/delimiter' top}{\pgfmathresult pt},
delimiter' bot/.code=\pgfmathparse{#1}% self-evaluating
\pgfkeyssetevalue{/tikz/delimiter' bot}{\pgfmathresult pt},
delimiter' top=0pt, delimiter' bot=0pt}
\makeatletter
\tikzset{
left delimiter'/.style={delimiter'={south east}{south west}
{every delimiter,every left delimiter,every left delimiter'}
{south}{north}{#1}{.}{\pgf@y}},
right delimiter'/.style={delimiter'={south west}{south east}
{every delimiter,every right delimiter,every right delimiter'}
{south}{north}{.}{#1}{\pgf@y}},
above delimiter'/.style={delimiter'={south east}{north west}
{every delimiter,every above delimiter,every above delimiter',rotate=-90}
{west}{east}{#1}{.}{\pgf@x}},
below delimiter'/.style={delimiter'={south west}{south west}
{every delimiter,every below delimiter,every below delimiter',rotate=-90}
{west}{east}{.}{#1}{\pgf@x}},
every delimiter'/.style={outer sep=+0pt,inner sep=+0pt,path only},
delimiter'/.style n args={8}{append after command={
\bgroup% similar to original delims
\pgfextra{\let\tikz@save@last@fig@name\tikz@last@fig@name
\tikz@node@is@a@labelfalse}
node[every delimiter',anchor=#1,at=(\tikz@last@fig@name.#2),#3,%
yshift=-\pgfkeysvalueof{/tikz/delimiter' bot}]{%
{\nullfont\pgf@process{%
\pgfpointdiff{\pgfpointanchor{\tikz@last@fig@name}{#4}}
{\pgfpointanchor{\tikz@last@fig@name}{#5}}}}%
$\left#6\vcenter{%
\hrule height\dimexpr.5#8+\pgfkeysvalueof{/tikz/delimiter' top}\relax
depth\dimexpr.5#8+\pgfkeysvalueof{/tikz/delimiter' bot}\relax
width0pt}\right#7$}
\pgfextra{\global\let\tikz@last@fig@name\tikz@save@last@fig@name}
\egroup}}}
\makeatother
\tikzset{
every left delimiter'/.style={
delimiter' top= \pgfkeysvalueof{/tikz/left delimiter top yshift},
delimiter' bot=-(\pgfkeysvalueof{/tikz/left delimiter bottom yshift})},
every right delimiter'/.style={
delimiter' top= \pgfkeysvalueof{/tikz/right delimiter top yshift},
delimiter' bot=-(\pgfkeysvalueof{/tikz/right delimiter bottom yshift})},
every above delimiter'/.style={
delimiter' top= \pgfkeysvalueof{/tikz/above delimiter right xshift},
delimiter' bot=-(\pgfkeysvalueof{/tikz/above delimiter left xshift})},
every below delimiter'/.style={
delimiter' top= \pgfkeysvalueof{/tikz/below delimiter right xshift},
delimiter' bot=-(\pgfkeysvalueof{/tikz/below delimiter left xshift})},
left delimiter top yshift/.initial=0pt,
left delimiter bottom yshift/.initial=0pt,
right delimiter top yshift/.initial=0pt,
right delimiter bottom yshift/.initial=0pt,
above delimiter left xshift/.initial=0pt,
above delimiter right xshift/.initial=0pt,
below delimiter left xshift/.initial=0pt,
below delimiter right xshift/.initial=0pt}
\tikzset{
ams/.style={
vcenter, inner sep=+0pt,
every delimiter/.style={yshift=+-1pt},
every left delimiter/.style={xshift=+ 2pt},
every right delimiter/.style={xshift=+-2pt}},
ams matrix/.style={
every outer matrix/.append style={inner sep=+1pt},
matrix anchor=center, matrix of math nodes,
row sep=1.5ex, column sep=2\arraycolsep},
create ams matrix/.style n args={3}{#1matrix/.style={
ams, every matrix/.style={
ams matrix, left delimiter'={#2}, right delimiter'={#3}}}},
create ams matrix/.list={b[], B\lbrace\rbrace, p(), v||, V\|\|},
ams delim' top/.style={
left delimiter top yshift={#1}, right delimiter top yshift={#1}},
ams delim' bot/.style={
left delimiter bottom yshift={#1}, right delimiter bottom yshift={#1}}}
\begin{document}
\hspace*{0.2em}
\tikz[bmatrix, ams delim' top=2ex]
\matrix {
\smash{1} & \smash{4} \\
7 & 10 \\
13 & 16 \\
};
%% ----------------
\hspace*{0.3em}
$\begin{bmatrix}
\smash{1} & \smash{4} \\
7 & 10 \\
13 & 16
\end{bmatrix}$
tikz matrix \hspace*{0.6em} bmatrix
\bigskip
\noindent
\foreach \top in {-3, -2.5, ..., 3}{
\tikz[bmatrix, ams delim' top=\top ex, ampersand replacement=\&]
\matrix[label=below:\tiny\color{gray}$\top$ex]{
\smash{1} \& \smash{4} \\ 7 \& 10 \\ 13 \& 16 \\};}
%
\tikz[
vcenter,
every below delimiter/.style={yshift=1.5ex},
below delimiter left xshift= 1ex,
below delimiter right xshift=-1ex,
above delimiter left xshift= 1ex,
above delimiter right xshift=-1ex,
]\matrix[
matrix of math nodes, above delimiter'=[, below delimiter'={]},
]{\smash{1} & \smash{4} \\ 7 & 10 \\ 13 & 16 \\};
\end{document}