使用 knots 包,我绘制了一个 (3,7) 环面结。我希望图表的内部区域显示为灰色。
以下是代码的最小工作示例。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{hobby,knots}
\begin{document}
\begin{tikzpicture}[use Hobby shortcut]
\fill[black!30!white] (90:1) \foreach \k in {1,...,7}{--(90+\k*360/7:1)};
\begin{knot}[
consider self intersections=true,
ignore endpoint intersections = false,
flip crossing/.list={1,7,6,11,10, 13, 15, 2}
]
\strand[very thick] ([closed]90:2) foreach \k in {1,...,7}
{ .. (90-360/7+\k*1080/7:1) .. (90+\k*1080/7:2) } (90:2);
\end{knot}
\end{tikzpicture}
\end{document}
该代码生成的图形如下所示。
该图的问题在于,我希望灰色区域能够整齐地贴合在其边界的结点图的弧线旁边。我想修复三个问题。
- 结 tikzlibrary 的工作原理是在交叉处出现的线束周围绘制较大的白色背景线。这就是实现上下交叉效果的方法(我认为)。我希望阴影区域忽略那些较大的白线并与结图的实际弧线相交。
- 我已经猜测了 \fill 命令中的交叉坐标。有没有办法计算出这些坐标的准确值?
- 内部区域的弧线与直线段非常接近。在这种情况下,我可能可以通过填充路径来解决问题(如果问题 1 得到解决)。但是,我不知道如何对一些具有曲线边界的区域进行着色。
任何帮助是极大的赞赏。
答案1
我不知道如何准确填充这个区域,但你可以像这样作弊:
\documentclass[tikz,border=7pt]{standalone}
\usetikzlibrary{hobby,knots,shapes}
\begin{document}
\begin{tikzpicture}[use Hobby shortcut]
\begin{knot}[
consider self intersections=true,
ignore endpoint intersections = false,
flip crossing/.list={1,7,6,11,10, 13, 15, 2}
]
\strand[very thick] ([closed]90:2) foreach \k in {1,...,7}
{ .. (90-360/7+\k*1080/7:1) .. (90+\k*1080/7:2) } (90:2);
\end{knot}
\node[regular polygon,regular polygon sides=7,fill,fill opacity=.21, inner sep=6.8mm, rotate=7] {};
\end{tikzpicture}
\end{document}
答案2
这是使用混合模式的方法(PGF 手册警告说,并非所有渲染器/打印机都支持这些模式)。其背后的想法是,结的白色部分应该遮盖结的其他部分,但不会遮盖其他任何东西。因此,所有内容最终都会进入混合组,我们会适当地选择混合模式。
为了获得实际区域,我们使用填充结点路径,even odd rule
并根据大小合适的圆圈进行裁剪(魔法数字由 www.i-just-made-them-up.com 提供)。这样我们就可以得到正确的区域(对于更通用的形状,可能需要在这一部分发挥一点创造力)。在顶部绘制结点有点奏效,但存在显示白色的问题,因此需要使用混合模式。
\documentclass{article}
%\url{https://tex.stackexchange.com/q/410096/86}
\usepackage{tikz}
\usetikzlibrary{hobby,knots}
\begin{document}
\begin{tikzpicture}[use Hobby shortcut]
\begin{scope}[blend group=darken]
\begin{scope}[blend group=normal,even odd rule]
\clip (0,0) circle[radius=1.07];
\fill[black!30!white, save Hobby path={knot}] ([closed]90:2) foreach \k in {1,...,7}
{ .. (90-360/7+\k*1080/7:1) .. (90+\k*1080/7:2) } (90:2);
\end{scope}
\begin{scope}[blend group=normal]
\begin{knot}[
consider self intersections=true,
ignore endpoint intersections = false,
flip crossing/.list={1,7,6,11,10, 13, 15, 2}
]
\strand[very thick] ([closed]90:2) foreach \k in {1,...,7} { .. (90-360/7+\k*1080/7:1) .. (90+\k*1080/7:2) } (90:2);
\end{knot}
\end{scope}
\end{scope}
\end{tikzpicture}
\end{document}
结果:
单个连接点的细节: