我想创建一个 tikz-macro,在给定的节点列表周围绘制一个漂亮的圆角多边形。类似的东西:
\myroundpoly{p1,p2,...,pn}{dist}
这里,p1,p2,....,pn
是按顺时针顺序给出的多边形的顶点,dist
是这些顶点的圆角多边形的距离的参数。
MWE 如下:
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usepackage{tkz-euclide}
\usetkzobj{all}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
%Some saple vertices
\node (a1) at (-1,-1) {1};
\node (a4) at (2,-2) {4};
\node (a3) at (3,3) {3};
\node (a2) at (-2,1) {2};
%---------------------------------------------------------------------%
%This is what I would like to type -> \myrondpoly{{a1,a2,a3,a4},0.3cm}%
%---------------------------------------------------------------------%
%----------------------------------%
%And this is what it should compute%
%----------------------------------%
\def\dist{0.3cm}
%Calculate the auxiliary coordinates for the arcs
\foreach \from/\to in {{a1/a2},{a2/a3},{a3/a4},{a4/a1}}{%calculates the points for the arcs and draws the straight lines
\coordinate (\from\to) at ($(\from)!\dist!90:(\to)$);
\coordinate (\to\from) at ($(\to)!\dist!-90:(\from)$);
}
%Draw the straight lines
\foreach \from/\to in {{a1/a2},{a2/a3},{a3/a4},{a4/a1}}
\draw (\from\to) -- (\to\from);
%Draw the arcs
\foreach \pred/\mid/\succ in {{a4/a1/a2},{a1/a2/a3},{a2/a3/a4},{a3/a4/a1}}{
\tkzDrawArc[color=black](\mid,\mid\succ)(\mid\pred)
}
\end{tikzpicture}
\end{document}
以下是一些值得拥有的功能列表:
多边形不应被填充,即,如果两个多边形重叠,则没有一个多边形会遮挡另一个多边形(当然,除了线条)
2 多边形和 1 多边形的特殊情况不会破坏代码
代码简短,软件包少
答案1
新答案
以下是最简单的方法
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\pgfdeclarelayer{background}
\pgfsetlayers{background,main}
\begin{document}
\def\drawpolygon#1,#2;{
\begin{pgfonlayer}{background}
\filldraw[line width=20,join=round ](#1.center)foreach\A in{#2}{--(\A.center)}--cycle;
\filldraw[line width=19,join=round,white](#1.center)foreach\A in{#2}{--(\A.center)}--cycle;
\end{pgfonlayer}
}
\tikz{
\node (a1) at (-1,-1) {1};
\node (a2) at (-2,1) {2};
\node (a4) at (2,-2) {4};
\node (a3) at (3,3) {3};
\node (a5) at (4,2) {5};
\node (a6) at (-1,3) {6};
\drawpolygon a2,a4,a3;
\drawpolygon a1,a5,a6;
}
\end{document}
旧答案
我有两种方法。第一种是纯钛钾Z。由于以下讨论的原因,它变得更加复杂使用 foreach 在多个节点之间绘制路径
第二个是纯 PGF,更简单。它们都支持 2 多边形(又名 digon)。
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\pgfdeclarelayer{background}
\pgfsetlayers{background,main}
\begin{document}
% pure TikZ version
\begin{tikzpicture}
\node (a1) at (-1,-1) {1};
\node (a2) at (-2,1) {2};
\node (a4) at (2,-2) {4};
\node (a3) at (3,3) {3};
\begin{pgfonlayer}{background}
\filldraw[line width=20,line join=round](a1.center)--(a2.center)--(a3.center)--(a4.center)--cycle;
\filldraw[line width=19,line join=round,white](a1.center)--(a2.center)--(a3.center)--(a4.center)--cycle;
\end{pgfonlayer}
\end{tikzpicture}
% pure pgf version
\def\drawpolygon#1,#2;{
\begin{pgfonlayer}{background}
\pgfsetroundjoin
\pgfpathmoveto{\pgfpointanchor{#1}{center}}
\foreach\P in{#2}{\pgfpathlineto{\pgfpointanchor{\P}{center}}}
\pgfpathclose\pgfsetlinewidth{20}\pgfsetcolor{black}\pgfusepath{fill,stroke}
\pgfpathmoveto{\pgfpointanchor{#1}{center}}
\foreach\P in{#2}{\pgfpathlineto{\pgfpointanchor{\P}{center}}}
\pgfpathclose\pgfsetlinewidth{19}\pgfsetcolor{white}\pgfusepath{fill,stroke}
\end{pgfonlayer}
}
\tikz{
\node (a1) at (-1,-1) {1};
\node (a2) at (-2,1) {2};
\node (a4) at (2,-2) {4};
\node (a3) at (3,3) {3};
\node (a5) at (4,2) {5};
\drawpolygon a2,a4,a3;
\drawpolygon a1,a5;
}
答案2
为了完整起见,我确实发布了我解决问题时使用的代码。它有很多缺陷:有时行不完全匹配,编译时间相当长,对于这样一个看似简单的问题来说,它的代码相当多。
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes}
%Necessary for the mypoly command%
\usepackage{tkz-euclide}
\usetkzobj{all}
\usepackage{xstring}
%------------------------%
%---The mypoly command---%
%------------------------%
%--Getting the last Element of a list--%
\def\splicelist#1{
\StrCount{#1}{,}[\numofelem]
\ifnum\numofelem>0\relax
\StrBehind[\numofelem]{#1}{,}[\mylast]%
\else
\let\mylast#1%
\fi
}
%--The mypoly macro--%
%How to use:
%\myroundpoly[decorative commands]{list of names of nodes}{distance}
%list of names has to be given in clockwise order
\newcommand{\myroundpoly}[3][thin,color=black]{
%Get the last element
\splicelist{#2}
%Calculate the auxiliary coordinates for the arcs
\foreach \vertex [remember=\vertex as \succvertex
(initially \mylast)] in {#2}{
\coordinate (\succvertex-next) at ($(\succvertex)!#3!90:(\vertex)$);
\coordinate (\vertex-previous) at ($(\vertex)!#3!-90:(\succvertex)$);
\draw[#1] (\succvertex-next) -- (\vertex-previous);
}
%Draw the arcs
\foreach \vertex in {#2}{
\tkzDrawArc[#1](\vertex,\vertex-next)(\vertex-previous)
}
}
%-------------------%
%---Some examples---%
%-------------------%
\begin{document}
\begin{tikzpicture}
%%%%%%%%%%%%
%This works%
%%%%%%%%%%%%
%--doing a triangle--%
\node (a1) at (0,0) {1};
\node (a2) at ($(a1)+(-120*1:1)$) {2};
\node (a3) at ($(a1)+(-120*2:1)$) {3};
\myroundpoly{a1,a2,a3}{0.3cm}
%--doing a 'cartwheel'--%
\node[circle, fill = black] (b0) at (2,0) {};
\node[circle, fill = black] (b1) at ($(b0)+(-120*1:1)$) {};
\node[circle, fill = black] (b2) at ($(b0)+(-120*2:1)$) {};
\node[circle, fill = black] (b3) at ($(b0)+(-120*3:1)$) {};
\myroundpoly[color = black, thick]{b3,b0,b2}{0.3cm}
\myroundpoly[color = black, thick]{b2,b0,b1}{0.3cm}
\myroundpoly[color = red]{b1,b0,b3}{0.3cm}
%%%%%%%%%%%%%%%%%%%%
%This does not work%
%%%%%%%%%%%%%%%%%%%%
\node (c1) at (5,0) {I};
\node (c2) at ($(c1)+(-120*1:1)$) {II};
\node (c3) at ($(c1)+(-120*2:1)$) {III};
\myroundpoly{c1,c3,c2}{0.3cm}%wrong order
\end{tikzpicture}
\end{document}