这是一条具有对称性的简单路径:
\begin{document}
\begin{tikzpicture}
\draw[thick] (0,0) -- ++(-9,0) -- ++(5,3) -- ++(2,7) -- ++(2,0);
\draw[green,thick] (0,10) -- ++(2,0) -- ++(2,-7) -- ++(5,-3) -- ++(-9,0);
\end{tikzpicture}
\end{document}
现在,不用手动绘制绿色部分,是否可以只说-- mirror cycle
或类似的话并自动绘制它?我知道有方法,如我们可以在 tikz 中镜像某个部分(“轴对称”、“反射”)吗?但是路径并不连续,并且需要一个额外的环境来复制路径,因此当路径改变时,维护工作不会减少。
答案1
可以用spath3
\documentclass[tikz, border=1cm]{standalone}
\usetikzlibrary{spath3}
\begin{document}
\begin{tikzpicture}
\path[spath/save=apath] (0, 0) -- ++(-9, 0) -- ++(5, 3) -- ++(2, 7) -- ++(2, 0);
\draw[thick, fill=green, spath/use=apath] [spath/transform={apath}{xscale=-1}, spath/use={apath, reverse, move, weld}] -- cycle;
\end{tikzpicture}
\end{document}
答案2
镜像轴位于X= 0,因此以符号为参数的简单宏是一个简单的解决方案。由于颜色变化,无论如何都不可能得到连续的解决方案:
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\draw[thick]
(0, 0) -- ++(-9, 0) -- ++(5, 3) -- ++(2, 7) -- ++(2, 0)
;
\draw[green, thick]
(0, 10) -- ++(2, 0) -- ++(2, -7) -- ++(5, -3) -- ++(-9, 0)
;
\end{tikzpicture}
\end{document}
连续解决方案更加复杂。例如,可以计算镜像点并以相反的顺序存储在列表中:
\documentclass[tikz]{standalone}
\newdimen\myX
\makeatletter
\newcommand*{\myInit}[1]{%
#1%
\pgfextra{%
\global\myX\pgf@x
\global\let\myList\@empty
}%
}
\newcommand*{\myNext}[1]{%
-- #1%
\pgfextra{%
\xdef\myList{%
--(\the\dimexpr2\myX-\pgf@x\relax,\the\pgf@y)%
\myList
}%
}%
}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw[thick, fill=lightgray]
\myInit{(0, 0)}
\myNext{++(-9, 0)}
\myNext{++(5, 3)}
\myNext{++(2, 7)}
\myList
-- cycle
;
\end{tikzpicture}
\end{document}
答案3
为了说明 Asymptote 中便捷的路径操作:reverse
,xscale
等等。
// copy to http://asymptote.ualberta.ca/ and click Run
unitsize(1cm);
path Lpath=(0,0)--(-9,0)--(-4,3)--(-2,10)--(0,10); // the left path
path Rpath=xscale(-1)*Lpath; // the right path is symmetric with the left to axis x=0
path mypath=Lpath--reverse(Rpath)--cycle; // the whole (closed) path
fill(mypath,lightgreen); // filling the whole path
draw(Lpath,red+2pt); // draw the left path
draw(Rpath,blue+2pt); // draw the right path
shipout(bbox(5mm,invisible)); // make the boundary bigger
更新对于整个路径来说更合适的是使用&
连接器,正如@NguyenVanChi1998 所建议的那样
path mypath=Lpath & reverse(Rpath) & cycle;