找回密码
 快速注册
搜索
查看: 603|回复: 4

tikz 的 arc 的边界框(bounding box)问题

[复制链接]

730

主题

1万

回帖

9万

积分

积分
93593
QQ

显示全部楼层

kuing 发表于 2021-7-23 16:33 |阅读模式
以下代码:
\fboxsep=0pt
\fbox{\tikz{\draw[red](0,0)circle(2);}}
\fbox{\tikz{\draw[red](1,1.732)arc(60:420:2);}}
得到:
QQ截图20210723162415.png
同样是画圆,用 arc 画会导致边界框比实际画出来的要大。

如果只是画一部分弧会如何呢?
比如 \fbox{\tikz{\draw[red](1,1.732)arc(60:300:2);}} ,效果:
QQ截图20210723162843.png
奇怪的是下方没大那么多,明明是对称的。

更细致的部分弧测试:
QQ截图20210723163100.png

这就类似于用 controls 来画贝塞尔曲线时,控制点也会影响边界框。
我怀疑 arc 内部可能也是类似处理,所以造成这样的结果。
但还是不理解为什么刚才那个对称的弧会上下不一样。

完整测试代码:
  1. \documentclass{article}
  2. \usepackage{tikz}
  3. \begin{document}
  4. \fboxsep=0pt
  5. \fbox{\tikz{\draw[red](0,0)circle(2);}}
  6. \fbox{\tikz{\draw[red](1,1.732)arc(60:420:2);}}
  7. \fbox{\tikz{\draw[red](1,1.732)arc(60:300:2);}}
  8. \foreach \i in {90,120,...,420} {\fbox{\tikz{\draw[red](1,1.732)arc(60:\i:2);}}\ }
  9. \end{document}
复制代码

730

主题

1万

回帖

9万

积分

积分
93593
QQ

显示全部楼层

 楼主| kuing 发表于 2021-8-11 15:22
学习了 TikZ 的 decorations.pathreplacing 这个 Library 之后,终于清楚了上述现象的原因。

该 Library 有个 show path construction 的功能,具体用法自行看手册,里面的第二个例子恰好可以用于这里。(稍改了一下)
  1. \documentclass{article}
  2. \usepackage{tikz}
  3. \usetikzlibrary{decorations.pathreplacing}
  4. \tikzset{
  5.     show curve controls/.style={
  6.         decoration={
  7.             show path construction,
  8.             curveto code={
  9.                 \draw [blue, dashed]
  10.                     (\tikzinputsegmentfirst)
  11.                     -- (\tikzinputsegmentsupporta)
  12.                     node [circle, fill, blue, inner sep=1pt]{}
  13.                     node [at start, circle, draw, solid, red, inner sep=1pt]{}
  14.                 ;
  15.                 \draw [green, dashed]
  16.                     (\tikzinputsegmentlast)
  17.                     -- (\tikzinputsegmentsupportb)
  18.                     node [circle, fill, green, inner sep=1pt]{}
  19.                     node [at start, circle, draw, solid, red, inner sep=1pt]{}
  20.                 ;
  21.             }
  22.         },decorate
  23.     }
  24. }
  25. \begin{document}
  26. \fboxsep=0pt
  27. \fbox{\tikz{\draw[postaction=show curve controls,red](0,0)circle(2);}}
  28. \fbox{\tikz{\draw[postaction=show curve controls,red](1,1.732)arc(60:420:2);}}
  29. \fbox{\tikz{\draw[postaction=show curve controls,red](1,1.732)arc(60:300:2);}}
  30. \foreach \i in {90,120,...,420} {\fbox{\tikz{\draw[postaction=show curve controls,red](1,1.732)arc(60:\i:2);}}\ }
  31. \end{document}
复制代码
效果:
QQ截图20210811151438.png
可以看到,实际上用 circle 画的圆(第一个圆)在内部同样是用贝塞尔曲线画出来的,只不过它的控制点与起点终点的连线与圆相切于上下左右,所以不会产生 bounding box 扩大的问题。
而后面用 arc 画的圆弧由于我以 60 度角为起角,所以就……(不描述啦,大家看图好啦……

再试一下抛物线和正余弦线,就拿手册里的例子(稍改一下):
  1. \fbox{\tikz \draw[x=10pt,y=10pt,postaction=show curve controls] (0,0) parabola bend (4,16) (6,12);}
  2. \fbox{\tikz \draw[postaction=show curve controls] (0,0) sin (1,1) cos (2,0) sin (3,-1) cos (4,0);}
复制代码
QQ截图20210811154059.png
都是切于极值,所以也不会扩大 bounding box。

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2023-4-9 06:22
ctan.org/pkg/tikz-bbox
\usetikzlibrary{bbox}

730

主题

1万

回帖

9万

积分

积分
93593
QQ

显示全部楼层

 楼主| kuing 发表于 2023-4-9 15:47
hbghlyj 发表于 2023-4-9 06:22
https://ctan.org/pkg/tikz-bbox
%usetikzlibrary{bbox}

相应宏包果然应运而生乃思!

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2023-4-9 18:29
本帖最后由 hbghlyj 于 2025-3-2 16:16 编辑 Asymptote自动计算精确的边界框:
size(6cm);

path bez = (0,0)..controls(-1,1)and(1,2)..(2,0);

draw(bez);

pair a = point(bez,0);
pair b = point(bez,1);

dot(a,Fill(white));
dot(b,Fill(white));

label("$(x_a,y_a)$",a,S);
label("$(x_b,y_b)$",b,S);

手机版|悠闲数学娱乐论坛(第3版)

GMT+8, 2025-3-4 12:05

Powered by Discuz!

× 快速回复 返回顶部 返回列表