悠闲数学娱乐论坛(第2版)'s Archiver

kuing 发表于 2018-6-11 03:35

tikz画带圈积分

问题来自:[url]http://bbs.ctex.org/forum.php?mod=viewthread&tid=155118[/url]

那帖楼主想要
[attach]6333[/attach]
这样的积分符号,主要是第二排第三个。

这种问题,最好的解决当然是能找到这套是什么字体(或相近的),但这要看运气。

那在既找不到也不会自己造字体的前提下,用tikz之类的包来画自然也是一种选择。

当然,如原帖第三页起所说的那样,用tikz搞出来的肯定不如专业设计的字体,所以这里只是一个尝试,纯粹是出于无聊,大家看看就好。

首先,适合用tikz画的也只有中间的圈,积分号还是得用字体,所以先选个相近的积分体先。

这里我找到了几年前不知在哪下载的积分号宏包:[attach]6334[/attach]用法是 \usepackage[参数]{varint}

其中参数为 euler 时的积分号就与上图的比较接近,但是没有带圈二三重:

[attach]6328[/attach]

在开始画圈之前,还得先考查一下这个积分号,因为根据[url=http://kuing.orzweb.net/viewthread.php?tid=4596]这帖[/url]的经验,积分号可能不是对称的,所以先用如下代码来框一下:
\newcommand\testsb[1]{%
\tikz[line width=0.1pt,baseline]{
\node[anchor=base,inner sep=0pt] (X) {\$#1\$} ;
\draw[gray] (X.north east) rectangle (X.south west)
(X.north east)--(X.south west) (X.north west)--(X.south east)
(X.north)--(X.south) (X.west)--(X.east);
}}
\testsb{\displaystyle\int}
[attach]6327[/attach]
果然还是不对称的,只不过偏差没默认的那么大,经过调试,需增加约 0.3mu 的距离来调整到中间。

开始画了,思路:通过重积分与单积分的宽度差来确定“跑道”的直线长度,圆半径由单积分宽度确定。
\newsavebox\intbox
\newsavebox\intboxx
\newcommand\intjq[5]{%
\sbox\intbox{\$#1#2#5\$}\sbox\intboxx{\$#1#3#5\$}%
\tikz[baseline={(0,0)},overlay,line width=0.1ex]{
\draw (\wd\intbox-0.5\wd\intboxx,0.5\ht\intbox-0.5\dp\intbox-#4\wd\intboxx)
arc [start angle=-90, end angle=90, radius=#4\wd\intboxx]
--++(\wd\intboxx-\wd\intbox,0)
arc [start angle=90, end angle=270, radius=#4\wd\intboxx]
--cycle;
}\!#2}

\newcommand\kkoint{\intjq{\displaystyle}{\int}{\int}{0.5}{\mkern0.3mu}}
\newcommand\kkoiint{\intjq{\displaystyle}{\iint}{\int}{0.5}{\mkern0.3mu}}
\newcommand\kkoiiint{\intjq{\displaystyle}{\iiint}{\int}{0.5}{\mkern0.3mu}}

这样,三种用于行间公式的带圈积分就出来了:

[attach]6329[/attach]

当然还要看一下有没有距离问题,上下标位置,这只需与没圈的对比即可:[code]\[
\begin{aligned}
k&=\int_u^ck & k&=\iint_u^ck & k&=\iiint_u^ck\\
k&=\kkoint_u^ck & k&=\kkoiint_u^ck & k&=\kkoiiint_u^ck\\
k&=\int\limits_u^ck & k&=\iint\limits_u^ck & k&=\iiint\limits_u^ck\\
k&=\kkoint\limits_u^ck & k&=\kkoiint\limits_u^ck & k&=\kkoiiint\limits_u^ck
\end{aligned}
\][/code][attach]6330[/attach]

甚至可以 \newcommand\kkoidotsint{\intjq{\displaystyle}{\idotsint}{\int}{0.5}{\mkern0.3mu}} 搞出酱紫的:[attach]6331[/attach]这……感觉有点丑……

行内的也类似,只是需增加的距离更小,0.1mu 左右,圈也要调小一点,如:
\newcommand\kktoint{\intjq{}{\int}{\int}{0.3}{\mkern0.1mu}}
\newcommand\kktoiint{\intjq{}{\iint}{\int}{0.3}{\mkern0.1mu}}
\newcommand\kktoiiint{\intjq{}{\iiint}{\int}{0.3}{\mkern0.1mu}}
[attach]6332[/attach]

至于 \scriptstyle 和 \scriptscriptstyle 的就不管了,大概也不会用到。

测试文档:[attach]6335[/attach](记得将上面的 varint.sty 放到同一目录下)

kuing 发表于 2018-6-12 02:44

改进一下:

\newsavebox\intbox
\newsavebox\intboxx
\newcommand\intjq[4]{[color=Red]\mathop{}\![/color]%
\sbox\intbox{\$#1#2#4\$}\sbox\intboxx{\$#1\int#4\$}%
\tikz[baseline={(0,0)},overlay,line width=[color=Red]0.08\wd\intboxx[/color]]{
\draw (\wd\intbox-0.5\wd\intboxx,0.5\ht\intbox-0.5\dp\intbox-#3\wd\intboxx)
arc [start angle=-90, end angle=90, radius=#3\wd\intboxx]
--++(\wd\intboxx-\wd\intbox,0)
arc [start angle=90, end angle=270, radius=#3\wd\intboxx]
--cycle;
}\!#2}

修改了三点,其中有一点是原先的参数#3多余,直接写 \int 即可。
另外两点为红色所标的地方,这里解释一下:
第一处如果不加,则积分号与前面的东西(比如系数)的有可能距离不对,昨晚测试时没试这种情况,所以没发现;
第二处改变后,线宽将由单积分号的宽度决定,这样做是为了做 \scriptstyle 和 \scriptscriptstyle 的,否则线宽不变。当然,在外面加 \text 也行,这是以前的处理方法,但今天测试时发现加 \text 的话编译速度会慢些,所以才想到了这样处理。

把 \scriptstyle 和 \scriptscriptstyle 的做了后,再将四个统一为一个命令 \Oint 等,就不用分行内行间来用了,具体代码见测试文档:[attach]6337[/attach]

效果:
[attach]6338[/attach]

kuing 发表于 2018-6-12 16:44

再次更新,稍微简化了一下代码,效果无变。

青青子衿 发表于 2019-4-10 12:16

[b]回复 [url=http://kuing.orzweb.net/redirect.php?goto=findpost&pid=27106&ptid=5429]3#[/url] [i]kuing[/i] [/b]
看看这里(MathJaX)
尽量能实现多少{:tongue:}
\begin{align*}
\circlearrowleft\!\!\!\!\!\!\!\int
\end{align*}

kuing 发表于 2019-4-10 17:48

[b]回复 [url=http://kuing.orzweb.net/redirect.php?goto=findpost&pid=30745&ptid=5429]4#[/url] [i]青青子衿[/i] [/b]

这里(MathJaX)也可以这样:
[precode]$A\int\llap\circlearrowleft B$
$$
A\int\llap{\circlearrowleft\,}B
$$[/precode]效果:
$A\int\llap\circlearrowleft B$
$$
A\int\llap{\circlearrowleft\,}B
$$

页: [1]

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.