shadow
shadow
这个人懒得不得了,竟然啥也没写

注册于 4年前

回答
21
文章
0
关注者
0

建议阅读 tkz-euclide 宏包手册与 pgf-tikz宏包手册第三部分

用纯 tikz 给一个弱的解答。思路是先求出多边形的重心,然后在重心到顶点射线的方向上的合适位置放置标签,用 calc 库计算坐标。

\documentclass[tikz,border=1cm]{standalone}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}
  \foreach \x/\y in {%
    (0,0)/a,
    (1,1)/b,
    (3,2)/c,
    (4,-1)/d,
  (2,-2)/e}
  { \node[fill, circle, inner sep =0pt, minimum size = 3pt] (\y) at \x {}; }
  \draw plot coordinates {(a) (b) (c) (d) (e) (a)};

  \coordinate (O) at ($0.2*(a)+ 0.2*(b)+ 0.2*(c)+ 0.2*(d)+ 0.2*(e)$);

  \fill[red] (O) circle(2pt);% 重心

  \foreach \x in {a,c,d,e}
  {\node at ($(O)!1.15!(\x)$){$\x$};}

  \node at ($(O)!1.22!(b)$){$b$};

\end{tikzpicture}

\end{document}

image.png

不难看到,用重心作为射线的起点并不完美,上图中的 b 标签就不能合适放置,故而只能单独绘制。

对于在圆上的凸多边形,存在到所有顶点距离相等的点,用该点作为射线起点比较合适,但对应一般的凸多边形不存在这样的点,所以仅仅用重心并不合适。

以上操作,本质上和逐个绘制标签没有区别,仅仅是用 foreach 简化操作。

给一个用 tikz 的 matrix 实现的方法,和上面的回答一致,但大括号用 \big 配合 \delimitershortfall 命令实现,主要用一下 \delimitershortfall

\documentclass[border=1cm,tikz]{standalone}

\usetikzlibrary {matrix, calc}

\begin{document}

\begin{tikzpicture}

  \matrix (m) [minimum width = 2em, minimum height = 3.5ex, matrix of nodes] {
    1 & 0 & 2 & 0 & -3\\

    0 & 1 & -1 & 0 & 4 \\

    0 & 0 & 0 & 1 & 1 \\

    0 & 0 & 0 & 0 & 0 \\
  };

  \draw[red, dashed] ($(m-1-1.north west)+(0.17,-0.13)$) |- (m-2-1.north east) |-(m-3-3.north east) |-($(m-4-5.north east)-(0.16,0)$);

  \delimitershortfall=-42pt
  \node at($(m.west)+(0.1,0)$) {$\big($ };
  \node at($(m.east)-(0.15,0)$) {$\big)$ };
\end{tikzpicture}

\end{document}

image.png

以上采用 node 的参数 minimum width, minimum height 控制元素的间距,使元素的间距更加均匀,也更容易控制虚线位于两列元素之间的中线位置。

使用 calc 库方便精调括号的位置。

实践中看到,delimitershortfall 的参数对括号的长度控制成梯状,比如 \delimitershortfall=-37\delimitershortfall=-42 大括号没有变化,但 \delimitershortfall=-43就会变长。

tikz 相较于 nicematrix 输出矩阵效率低,但可以调细节,各取所需。

针对等号上下的公式,给两种方法:

1. 借助 extarrows 宏包的 \xlongequal 命令

% \usepackage{extarrows}

\[
A \xlongequal[r_2 - r_1]{\substack{\scalebox{0.7}{$r_4 + 2r_3$} \\[1ex]r_2 + r_1\\[1ex]}} B
\]

image.png

2. 使用 array 环境,不过还需要 mathtools 宏包:

% \usepackage{mathtools,extarrows}

\[
A \xlongequal[r_2 - r_1]{\scalebox{0.8}{$\begin{array}{c}
\scalebox{0.9}{$r_4 + 2r_3$}\\[0.5ex]
r_2 + r_1\\[0.5ex]
\end{array}$}} B
\]

image.png

此外,还可以使用 tikz 局部造符号,有兴趣可以自己试试。

给一个比较愚蠢的方法,与 nicematrix 无关,仅仅作为一种方法。用 tikz 的 matrix 库实现

\documentclass[tikz,border=1cm]{standalone}

\usetikzlibrary{matrix,calc}

\begin{document}

\begin{tikzpicture}

  \matrix (m) [matrix of math nodes,
    left delimiter=(,
    right delimiter=),
    inner sep=1pt, column sep=8pt,
    row sep=8pt,
  ]
  {
    A_{11} & A_{12} & \dots & A_{1s} \\
    A_{21} & A_{22} & \dots & A_{2s} \\
    \vdots & \vdots & \ddots & \vdots \\
    A_{r1} & A_{r2} & \dots & A_{rs} \\
  };

  \foreach \x/\y in {1/1,2/2,4/s}
  {
    \node[align=center] at ($(m-1-\x.north)+(0,0.27)$) {\scalebox{0.8}{$n_{\y}$}\\[-1ex]
    \scalebox{0.65}{\rotatebox{90}{$\bigg\}$}}
  };
}

\foreach \x/\y in {1/1,2/2,4/r}
{
  \node[align=center] at ($(m-\x-4)+(1,0)$) {\scalebox{0.9}{$\big\}$}\,\scalebox{0.8}{$m_{\y}$}
};
}

\node at ($(m-1-3.north)+(0.03,0.35)$){$\cdots$};
\node at ($(m-3-4)+(0.85,0)$){$\vdots$};
\end{tikzpicture}

\end{document}

image.png

可以看到,一些元素的间距处理比较麻烦而且效果不完美,用 nicematrix 处理更好。

重新写一下回答:

答案 2 的思路基本上就是我在群里说的思路,下面对 node 的形状为 circle 的情况,借助 pgfkey 封装成一个命令

\documentclass[tikz,border=5pt]{standalone}
\usetikzlibrary{calc}

\makeatletter
\pgfkeys{
  /tikz/dash circle/minsize/.code    = \def\dc@min{#1},
  /tikz/dash circle/segments/.code   = \def\dc@seg{#1},
  /tikz/dash circle/radio/.code      = \def\dc@rat{#1}
}

\pgfkeys{
  /tikz/dash circle/.code = {%
    \pgfqkeys{/tikz/dash circle}{#1}%

    \@ifundefined{dc@min}{\errmessage{dash circle: 'minsize' is required}}{}
    \@ifundefined{dc@seg}{\errmessage{dash circle: 'segments' is required}}{}
    \@ifundefined{dc@rat}{\errmessage{dash circle: 'radio' is required}}{}

    \pgfmathsetmacro{\dc@circ}{pi * \dc@min}
    \pgfmathsetmacro{\dc@on}{(\dc@rat / (\dc@rat + 1)) * \dc@circ / \dc@seg}
    \pgfmathsetmacro{\dc@off}{(1 / (\dc@rat + 1)) * \dc@circ / \dc@seg}

    \tikz@addoption{%
      \pgfsetdash{{\dc@on pt}{\dc@off pt}}{0pt}%
      \pgfkeysalso{/tikz/shape=circle}%
    }
  }
}
\makeatother

\begin{document}
\begin{tikzpicture}[nodes={draw, line width=1pt, red, font=\LARGE, text = blue}]
\node[draw, minimum size=3cm, dash circle={minsize=3cm, segments=10, radio=2}] at (0,0) {ABC};

\node[draw, minimum size=3cm, dash circle={minsize=3cm, segments=20, radio=2}] at (6,0) {ABC};

\node[draw, minimum size=3cm, dash circle={minsize=3cm, segments=10, radio=1}] at (0,-4) {ABC};

\node[draw, minimum size=2cm, dash circle={minsize=2cm, segments=10, radio=1}] at (6,-4) {ABC};
\end{tikzpicture}
\end{document}

image.png

其中 minisize 是 node 的 minimum size 的值,segments 是虚线的节数,radio 是 on 与 off 的比值,这比输入 on 或者 off 的值更加自然。

此外,该命令未将 minimum size 放进,也就是说用户需要在命令外重新输入 node 的 minimum size,这样是为了形式更加自然,因为本质上这个命令只是用来输入虚线的样式,不控制 node 的边界大小等内容。

缺陷: 该命令是用 node 的 minimum size 来计算 node 边界周长,这导致如果 node 内使用 inner sep 参数可能会使虚线起始点交汇处依然存在问题。

对于一般的 node 形状,涉及周长的计算,通用的解决方法可能比较困难,欢迎大家给出解答。

问题 5\bigl 等命令能更加随意的改变定界符的大小以适应不同大小的公式,\left, \right命令也能一定程度的自适应公式大小,但这种适应只能覆盖一小部分场景。

本质上,这二者都是 TeX 层面的命令,它们都受 \delimiterfactor\delimitershortfall 的影响,具体见 TeXbook

image.png

下面的例子可以看到 \delimiterfactor 对二者的影响程度不同
image.png

此外,\bigl, \bigr, \bigm, \big 等命令之间的差别就是定界符和公式之间的水平间距
image.png

用 tikz 的 matrix 模块给一种方法(在这种情况下它并非是最优解)

\documentclass{article}
\usepackage{amsmath,tikz}
\usetikzlibrary{matrix}

\begin{document}

\begin{equation}
  \begin{tikzpicture}[baseline=(current bounding box.center)]
    \matrix [matrix of math nodes, nodes={anchor=east},]{
      \frac{1}{\sqrt{2}}y_1  & -                  & \frac{1}{\sqrt{2}}y_2  &         & = & f_1\\
      \frac{1}{\sqrt{2}}y_1  & +                  & \frac{1}{\sqrt{2}}y_2  &         & = & f_2\\
                             & \textcolor{red}{+} & \frac{1}{\sqrt{2}}y_2  & + \,y_3 & = & f_3\\
                             & \textcolor{red}{+} & -\frac{1}{\sqrt{2}}y_2 &         & = & f_4\\
      \frac{1}{\sqrt{2}}y_1  &                    &                        & - \,y_3 & = & f_5\\
      -\frac{1}{\sqrt{2}}y_1 &                    &                        &         & = & f_6\\
    };
  \end{tikzpicture}
\end{equation}

\begin{equation}
  a + b =c
\end{equation}

\end{document}

结果如下

image.png

其中 [baseline=(current bounding box.center)] 是为了使 matrix 的公式编号垂直居中。

以上使用的是 equation 环境的自动编号,如果想使用手动编号,只需在 tikzpicture 环境后添加\tag{...}.

该方法对于公式中不同行列等间距输出的情况不是最优解,而对于行列不等间距的情况是比较方便的(因为 matrix 模块可以轻松指定 row sep, column sep 或者在 &\\后添加增量距离来实现改变行列间距)。

lshort 中有提到扩展的内容,需要什么就找对应的宏包手册,有了初步知识后就可以实践,在排版过程中遇到问题就找对应宏包学习。此外可以问问 ai,它给出大致的范围,找对应资料再详细了解。

如果局部修改,建议采用垂直距离命令(诸如\vskip,\vspace*{}等),如果全局修改,可以修改\abovedisplayskip\belowdisplayskip,示例如下

\documentclass{ctexart}

\usepackage{amsmath}

\makeatletter
\renewcommand\normalsize{%
  \@setfontsize\normalsize\@xpt\@xiipt
  \abovedisplayskip 20pt plus 3pt minus 3pt
  \belowdisplayskip 20pt plus 3pt minus 3pt
}
\makeatother

\begin{document}

一些文本一些文本一些文本一些文本
\[
1+2=3
\]
一些文本一些文本一些文本一些文本一些文本

\end{document}

image.png
也可以将其放入 group 内,修改一部分区域。

symbol-a4上有诸多数学符号字体,可以试试...

针对求和号右上角的 prime:

% \usepackage{amsmath}
\[
\sideset{}{'}{\sum}
\]

02696e0a4606e3ab346b4ad24ccb8cb4.png

给个笨办法,先画一遍一种颜色的,再对需要变颜色的地方重新描一遍。

如果图形有比较多重复的地方,可以设置自定义宏减少工作量。

另外不知道能不能做一个这样的功能:能只对 draw 的某一 x 和 y 的坐标范围给予特定参数效果,这样不仅对染色,还对其他修饰也起作用。

一个简单粗暴的方法,但自由度比较高:

\begin{equation} 
\left\{
\begin{aligned}
    &\dot{X}(t)=AX(t)+Bw(0,t), &&t\in(0,T),\\
    &w_t(x,t)-w_{xx}(x,t)=0, &&x\in[0,D],t\in(0,T),\\
    &w(0,t)=\gamma(D)X(t)\\
    &\hspace*{3.1em}  \displaystyle{
        +\int_{0}^{D}\left(\int_{0}^{D-y}\gamma(\sigma)d\sigma\right) Bu(y,t)dy},&& t\in(0,T),
\end{aligned}
\right.
\end{equation}

应该有特定的环境支持,一时想不起来了。

发布
问题