新答案

新答案

我想创建一个 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}

圆角多边形的一些示例

相关内容