我想在下图中的白色区域周围添加粗边框,同时保留灰色区域的虚线。有没有简单的方法可以做到这一点?
我的代码如下。谢谢!
\begin{tikzpicture}
\clip (-4.5,-4) rectangle (4.5,4);
\filldraw[fill=white](-4.5,-4) rectangle (4.5,4);
\fill[fill=gray!50] (115 : 2 + 5) circle (5);
\fill[fill=gray!50] (45 : 2 + 8) circle (8);
\fill[fill=gray!50] (180 : 2 + 10) circle (10);
\fill[fill=gray!50] (345 : 2 + 7) circle (7);
\fill[fill=gray!50] (270 : 2 + 9) circle (9);
\draw[dashed] (115 : 2 + 5) circle (5);
\draw[dashed] (45 : 2 + 8) circle (8);
\draw[dashed] (180 : 2 + 10) circle (10);
\draw[dashed] (345 : 2 + 7) circle (7);
\draw[dashed] (270 : 2 + 9) circle (9);
\end{tikzpicture}
更新:
使用建议的方法Q238967,我已经能够接近了,但其中一行有问题。我在下面添加了更新的代码以及新图像。
\begin{tikzpicture}
\clip (-4.5,-4) rectangle (4.5,4);
\filldraw[fill=white](-4.5,-4) rectangle (4.5,4);
\fill[fill=gray!50] (45 : 2 + 8) circle (8);
\fill[fill=gray!50] (115 : 2 + 5) circle (5);
\fill[fill=gray!50] (180 : 2 + 10) circle (10);
\fill[fill=gray!50] (270 : 2 + 9) circle (9);
\fill[fill=gray!50] (345 : 2 + 7) circle (7);
\draw[name path=one, dashed] (45 : 2 + 8) circle (8);
\draw[name path=two, dashed] (115 : 2 + 5) circle (5);
\draw[name path = three, dashed] (180 : 2 + 10) circle (10);
\draw[name path = four, dashed] (270 : 2 + 9) circle (9);
\draw[name path = five, dashed] (345 : 2 + 7) circle (7);
\path[name path = temp1, red, intersection segments={of=one and two,sequence=R2}];
\draw[red,ultra thick, intersection segments={of=temp1 and three,sequence=L3}];
\path[name path = temp2, red, intersection segments={of=one and five,sequence=L1}];
\draw[red,ultra thick, intersection segments={of=temp2 and two,sequence=L3}];
\path[name path = temp3, red, intersection segments={of=four and five,sequence=L3}];
\draw[red,ultra thick, intersection segments={of=temp3 and three, sequence=L1}];
\path[name path = temp4, red, intersection segments={of=three and four,sequence=L1}];
\draw[red,ultra thick, intersection segments={of=temp4 and two, sequence=L1}];
\path[name path = temp5, red, intersection segments={of=one and five,sequence=R3}];
\draw[red,ultra thick, intersection segments={of=temp5 and four, sequence=L1}];
\end{tikzpicture}
答案1
左边的圆确实很麻烦,因为从内部看,它仍然是一个从 0 角开始向四周延伸的圆弧。这将导致额外的分割。
这是我对此的看法,将虚线部分做成圆弧,这样就不会发生这种分割。通过选择一个小角度,我们在每对圆(现在是圆弧)之间也只有一个交点。
我fillbetween
觉得没有一个好的解决方案,那就是在两个片段之间只保留一条路径,而没有移动,这就是我line cap = round
在这里使用的原因,以隐藏这一事实。inner moveto
(实际上它似乎在/pgf/fill between/
名称空间中)但我不知道应该如何使用它。示例甚至没有使用它。
这就是我提供spath3
解决方案的原因。
在我们完成split at intersections
每对路径并移除每条路径上的第一个和第三个/最后一个段之后,我们剩下五个只需要连接的路径段。
与fillbetween
解决方案相反,我们实际上可以将各部分连接起来,这样它就会成为一条连续的路径。现在,连接不仅看起来不错,而且我们还可以使用路径包含的整个区域来正确填充、着色或图案化。
请记住,所有圆和圆弧都是逆时针构造的,并且圆的枚举方式相同。但是,这意味着我们必须顺时针构造内部区域,这就是为什么\draw
两个解决方案中的最终结果都是 4、3、2、1、0。
是的,我开始计数,0
因为这样可以更容易地对路径进行模运算(如spath3
解决方案所示)。
代码 (fillbetween
)
\documentclass[tikz]{standalone}
\usepackage{pgfplots}\pgfplotsset{compat=newest}
\usetikzlibrary{pgfplots.fillbetween}
\begin{document}
\begin{tikzpicture}
\clip (-4.5,-4) rectangle (4.5,4);
\foreach \ang/\rad in {45/8, 115/5, 180/10, 270/9, 345/7}
\fill[gray!50] (\ang:2+\rad) circle[radius=\rad];
\tikzset{
arc path/.code args={#1/#2/#3}{% ungrouped loop
\draw[dashed, name path=p#1] ([shift=(#2+135:#3)]#2:2+#3)
arc[start angle=#2+135, delta angle=90, radius=#3];},
arc path/.list={0/45/8, 1/115/5, 2/180/10, 3/270/9, 4/345/7},
split paths/.code 2 args={
\path[intersection segments={of=p#1 and p#2, sequence=R1}, name path=p#2 on p#1];},
split paths/.list={01, 12, 23, 34, 40}
}
\draw[ultra thick, line cap=round,
intersection segments/.list={{of=p4 and p3 on p2, sequence=R2},
{of=p3 and p2 on p1, sequence=R2},
{of=p2 and p1 on p0, sequence=R2},
{of=p1 and p0 on p4, sequence=R2},
{of=p0 and p4 on p3, sequence=R2}}];
\end{tikzpicture}
\end{document}
代码 (spath3
)
\documentclass[tikz]{standalone}
\usetikzlibrary{spath3, intersections}
\newcommand*\NextOf[2]{\pgfintmod{#1+1}{#2}}
%\newcommand*\PrevOf[2]{\pgfintmod{#1-1}{#2}}
\begin{document}
\begin{tikzpicture}
\clip (-4.5,-4) rectangle (4.5,4);
\foreach \ang/\rad in {45/8, 115/5, 180/10, 270/9, 345/7}
\fill[gray!50] (\ang:2+\rad) circle[radius=\rad];
\tikzset{
arc path/.code args={#1/#2/#3}{% ungrouped loop
\draw[dashed, spath/save=p#1] ([shift=(#2+135:#3)]#2:2+#3)
arc[start angle=#2+135, delta angle=90, radius=#3];},
arc path/.list={0/45/8, 1/115/5, 2/180/10, 3/270/9, 4/345/7},
split paths/.style={spath/split at intersections={p#1}{p\NextOf{#1}{5}}},
split paths/.list={0, ..., 4},
remove start and end/.style={spath/remove components={p#1}{1, 3}},
remove start and end/.list={0, ..., 4},
}
\draw[
line width=1ex,
spath/append no move/.list={p4, p..., p0},
spath/adjust and close=current];
\end{tikzpicture}
\end{document}
输出 (spath3
)
答案2
您也可以使用方便的buildcycle
宏来执行此操作元帖子,但你需要小心如何构造圆。特别是你需要确保旋转它们,这样没有一个point 0
点位于任何其他圆内。纯粹为了比较,这是我的努力:
使用以下命令进行编译lualatex
:
\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
path C[];
C1 = fullcircle scaled 300 rotated 115 shifted 210 dir 115;
C2 = fullcircle scaled 480 rotated 45 shifted 300 dir 45;
C3 = fullcircle scaled 420 rotated 345 shifted 270 dir 345;
C4 = fullcircle scaled 540 rotated 270 shifted 330 dir 270;
C5 = fullcircle scaled 600 rotated 180 shifted 360 dir 180;
path S; S = unitsquare shifted -(1/2,1/2) scaled 300;
for i = 1 upto 5:
C[i] := C[i] cutbefore S cutafter S;
endfor
path P; P = buildcycle(C1, C2, C3, C4, C5);
beginfig(1);
fill S withcolor 7/8;
fill P withcolor 7/8[red, white];
draw S;
draw P withpen pencircle scaled 1 withcolor 2/3 red;
for i=1 upto 5:
draw C[i] dashed evenly;
endfor
endfig;
\end{mplibcode}
\end{document}
如果希望红线隐藏虚线,则将draw P
线移到绘制圆弧的循环之后。而且您可能不想要任何颜色,因此类似这样的方法可能更好:
beginfig(1);
fill S withcolor 7/8;
fill P withcolor background;
draw S;
for i=1 upto 5:
draw C[i] dashed evenly;
endfor
draw P withpen pencircle scaled 1;
endfig;
其结果为:
笔记
单位为 PostScript 点 28.35 = 1cm
您可以使用宏在 MP 中执行极坐标
dir
。表达式dir 100
扩展为right rotated 100
,从而给出位于单位圆上的<pair>
值。表达式将此点缩放为半径为 200bp 和角度为 100° 的极坐标。(sind 100, cosd 100)
200 dir 100
如果你使用默认单位(PostScript 点),效果会更好,因为你可以
200 dir 45
直接书写。能使用cm
等等,但是你必须写得7 cm * dir 45
不那么优雅。请注意,在这个习语中,
fullcircle scaled 300 rotated 115 shifted 210 dir 115;
数字分别代表点、度、点和度。
答案3
我对这个套餐不太熟悉,spath
但只是为了好玩和空闲时间
根据@AndrewStacy 给出的答案推断出来的答案——
https://tex.stackexchange.com/a/682553/197451
发起者可以建议
\documentclass[margin=5mm]{standalone}
\usepackage{ pgfplots}
\usetikzlibrary{calc,intersections, fillbetween, spath3}
\begin{document}
\begin{tikzpicture}
\clip (-5,-5) rectangle (5,5);
\filldraw[fill=white](-5,-5) rectangle (5,5);
\fill[fill=gray!50] (45 : 2 + 8) circle (8);
\draw[spath/save=circle8, dashed] (45 : 2 + 8) circle (8);
\fill[fill=gray!50] (115 : 2 + 5) circle (5);
\draw[spath/save=circle5, dashed] (115 : 2 + 5) circle (5);
\fill[fill=gray!50] (180 : 2 + 10) circle (10);
\draw[spath/save=circle10, dashed] (180 : 2 + 10) circle (10);
\fill[fill=gray!50] (270 : 2 + 9) circle (9);
\draw[spath/save=circle9, dashed] (270 : 2 + 9) circle (9);
\fill[fill=gray!50] (345 : 2 + 7) circle (7);
\draw[spath/save=circle7, dashed] (345 : 2 + 7) circle (7);
%
\tikzset{%
spath/split at intersections={circle8}{circle5},
spath/split at intersections={circle5}{circle10},
spath/split at intersections={circle10}{circle9},
spath/split at intersections={circle9}{circle7},
spath/split at intersections={circle7}{circle8},
spath/get components of={circle8}\cptsA,
spath/get components of={circle5}\cptsB,
spath/get components of={circle10}\cptsC,
spath/get components of={circle9}\cptsD,
spath/get components of={circle7}\cptsE,
spath/get components of={circle8}\cptsF,
}
\draw[
red,
thick,
spath/use=\getComponentOf{\cptsA}{-2},
spath/use={\getComponentOf{\cptsB}{-3}},
spath/use={\getComponentOf{\cptsC}{-2}},
spath/use={\getComponentOf{\cptsD}{-2}},
spath/use={\getComponentOf{\cptsE}{-2}},
spath/use={\getComponentOf{\cptsF}{3}},
];
%
\end{tikzpicture}
\end{document}
输出
编辑
根据@AndrewStacey 的评论,所有虚线也可见
\documentclass[margin=5mm]{standalone}
\usepackage{ pgfplots}
\usetikzlibrary{calc,intersections, fillbetween, spath3}
\begin{document}
\begin{tikzpicture}
\clip (-5,-5) rectangle (5,5);
\filldraw[fill=white](-5,-5) rectangle (5,5);
\fill[fill=gray!50] (45 : 2 + 8) circle (8);
\fill[fill=gray!50] (115 : 2 + 5) circle (5);
\fill[fill=gray!50] (180 : 2 + 10) circle (10);
\fill[fill=gray!50] (270 : 2 + 9) circle (9);
\fill[fill=gray!50] (345 : 2 + 7) circle (7);
\draw[spath/save=circle8, dashed] (45 : 2 + 8) circle (8);
\draw[spath/save=circle5, dashed] (115 : 2 + 5) circle (5);
\draw[spath/save=circle10, dashed] (180 : 2 + 10) circle (10);
\draw[spath/save=circle9, dashed] (270 : 2 + 9) circle (9);
\draw[spath/save=circle7, dashed] (345 : 2 + 7) circle (7);
%
\tikzset{%
spath/split at intersections={circle8}{circle5},
spath/split at intersections={circle5}{circle10},
spath/split at intersections={circle10}{circle9},
spath/split at intersections={circle9}{circle7},
spath/split at intersections={circle7}{circle8},
spath/get components of={circle8}\cptsA,
spath/get components of={circle5}\cptsB,
spath/get components of={circle10}\cptsC,
spath/get components of={circle9}\cptsD,
spath/get components of={circle7}\cptsE,
spath/get components of={circle8}\cptsF,
}
\draw[
blue,
thick,
spath/use=\getComponentOf{\cptsA}{-2},
spath/use={\getComponentOf{\cptsB}{-3}},
spath/use={\getComponentOf{\cptsC}{-2}},
spath/use={\getComponentOf{\cptsD}{-2}},
spath/use={\getComponentOf{\cptsE}{-2}},
spath/use={\getComponentOf{\cptsF}{3}},
];
%
\end{tikzpicture}
\end{document}
输出