如何使用 tikz 绘制任意多字母组合?

如何使用 tikz 绘制任意多字母组合?

我一直在尝试创建一个命令来概括这一点,但我不知道我做错了什么。也许它比我想象的要复杂。我该怎么做?请包括步骤描述,因为我对 latex 和 tikz 了解不多。还请解释一下我做错了什么。

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\begin{document}
\newcommand{\polygram}[4]{%radius, number of total points, connect points skipping this number of points, draw options
\draw[#4] ({360/#2}:#1) %draw at starting point
\foreach \x in {1, ..., #2} %cycle through other points, drawing to the next, skipping #3 points
{ -- ({360/(\x+#3)}:#1)} -- cycle;
}

\tikz \polygram{2}{5}{2}{blue};

\end{document}

更多信息:宝丽金(维基百科)

答案1

我认为,你所追求的是这样的:

\documentclass[tikz, border=1cm]{standalone}
\begin{document}

\newcommand{\polygram}[4][]{
    % options, radius, # of total points, # of skipping points
    \draw[#1] (0:#2) 
    \foreach \x in {1,...,#3} {
        -- ({360/#3*(\x-1)*#4}:#2) 
    } -- cycle
}

\tikz \polygram[blue]{2}{5}{2};

\end{document}

在此处输入图片描述

作为比较,\tikz \polygram[blue]{2}{10}{3};结果是:

在此处输入图片描述


请注意,0 度是在右边。为了绘制起点向上的图表,您需要将所有内容逆时针旋转 90 度:

\documentclass[tikz, border=1cm]{standalone}
\begin{document}

\newcommand{\polygram}[4][]{
    % options, radius, # of total points, # of skipping points
    \draw[#1] (90:#2) 
    \foreach \x in {1,...,#3} {
        -- ({360/#3*(\x-1)*#4+90}:#2) 
    } -- cycle
}

\tikz \polygram[blue]{2}{5}{2};

\end{document}

在此处输入图片描述


而且因为我最近非常喜欢pics,所以使用 s 的解决方案是pic

\documentclass[tikz, border=1cm]{standalone}
\begin{document}

\tikzset{
    pics/polygram/.style={
        code={
            \tikzset{polygram/.cd, #1}
            \draw[pic actions] (90:{\pgfkeysvalueof{/tikz/polygram/radius}}) 
                \foreach \x in {1,...,{\pgfkeysvalueof{/tikz/polygram/total points}}} {
                    -- ({ 360 /
                          \pgfkeysvalueof{/tikz/polygram/total points} *
                          (\x - 1) * 
                          \pgfkeysvalueof{/tikz/polygram/skipping points} + 
                          90 } : 
                        {\pgfkeysvalueof{/tikz/polygram/radius}}) 
                } -- cycle;    
        }
    },
    polygram/.cd,
    radius/.initial=1,
    total points/.initial=5,
    skipping points/.initial=2,
}

\tikz \pic[blue] {polygram={radius=2}};

\tikz \pic[red, thick] {polygram={total points=7}};

\tikz \pic[cyan, dashed] {polygram={radius=2, total points=7, skipping points=3}};

\end{document}

在此处输入图片描述


此版本还适用于(总分)和(跳过的点数)可以被整除:

\documentclass[tikz, border=1cm]{standalone}
\begin{document}

\tikzset{
    pics/polygram/.style={
        code={
            \tikzset{polygram/.cd, #1}
            \pgfmathparse{
                mod(
                    \pgfkeysvalueof{/tikz/polygram/total points} ,
                    \pgfkeysvalueof{/tikz/polygram/skipping points} 
                ) == 0 ? \pgfkeysvalueof{/tikz/polygram/skipping points} : 1
            }
            \foreach \r in {0,...,\pgfmathresult} {
                \begin{scope}[rotate={360/\pgfkeysvalueof{/tikz/polygram/total points}*\r}]
                    \draw[pic actions] (90:{\pgfkeysvalueof{/tikz/polygram/radius}}) 
                        \foreach \x in {1,...,{\pgfkeysvalueof{/tikz/polygram/total points}}} {
                            -- ({ 360 /
                                  \pgfkeysvalueof{/tikz/polygram/total points} *
                                  (\x - 1) * 
                                  \pgfkeysvalueof{/tikz/polygram/skipping points} + 
                                  90 } : 
                                {\pgfkeysvalueof{/tikz/polygram/radius}}) 
                        } -- cycle;
                \end{scope}
            }
        }
    },
    polygram/.cd,
    radius/.initial=1,
    total points/.initial=5,
    skipping points/.initial=2,
}

\tikz \pic[blue] {polygram={total points=12, skipping points=4}};

\tikz \pic[blue] {polygram={total points=6, skipping points=2}};

\end{document}

在此处输入图片描述


进行调整以便能够单独设置不同图层的样式并在尖端添加可设置样式的点:

\documentclass[tikz, border=1cm]{standalone}
\begin{document}

\tikzset{
    pics/polygram/.style={
        code={
            \tikzset{polygram/.cd, #1}
            \pgfmathsetmacro{\polygramlayers}{
                mod(
                    \pgfkeysvalueof{/tikz/polygram/total points} ,
                    \pgfkeysvalueof{/tikz/polygram/skipping points} 
                ) == 0 ? \pgfkeysvalueof{/tikz/polygram/skipping points} : 1
            }
            \pgfmathsetmacro{\polygramnodesperlayer}{
                int(
                    \pgfkeysvalueof{/tikz/polygram/total points} / 
                    \polygramlayers 
                )
            }
            \foreach \r in {1,...,\polygramlayers} {
                \tikzset{polygram layer \r/.initial={}}
                \begin{scope}[
                    rotate={360/\pgfkeysvalueof{/tikz/polygram/total points}*\r}, 
                    pic actions,
                    polygram layer \r
                ]
                    \draw (90:{\pgfkeysvalueof{/tikz/polygram/radius}}) 
                            node[polygram dot] {}   
                        \foreach \x in {1,...,\polygramnodesperlayer} {
                            -- ({ 360 /
                                  \pgfkeysvalueof{/tikz/polygram/total points} *
                                  (\x - 1) * 
                                  \pgfkeysvalueof{/tikz/polygram/skipping points} + 
                                  90 } : 
                                {\pgfkeysvalueof{/tikz/polygram/radius}}) 
                                    node[polygram dot] {}
                        } -- cycle;
                \end{scope}
            }
        }
    },
    polygram dot/.style={circle, fill, inner sep=1pt},
    polygram/.cd,
    radius/.initial=1,
    total points/.initial=5,
    skipping points/.initial=2,
}

\tikz 
    \pic[blue, 
        polygram dot/.append style={draw=black},
        polygram layer 1/.style={magenta, thick, polygram dot/.append style={fill=orange}}, 
        polygram layer 2/.style={red}
    ] 
    {polygram={total points=12, skipping points=4}};

\tikz 
    \pic[blue] {polygram={total points=5, skipping points=3}};

\end{document}

在此处输入图片描述


最后一种变体的非pic版本将是:

\documentclass[tikz, border=1cm]{standalone}
\begin{document}

\tikzset{
    polygram dot/.style={circle, fill, inner sep=1pt}
}

\newcommand{\polygram}[4][]{
    % options, radius, # of total points, # of skipping points
    \pgfmathsetmacro{\polygramlayers}{
        mod(#3,#4) == 0 ? #4 : 1
    }
    \pgfmathsetmacro{\polygramnodesperlayer}{
        int(#3/\polygramlayers)
    }
    \node at (0,0) {\polygramlayers};
    \foreach \r in {0,...,\polygramlayers} {
        \tikzset{polygram layer \r/.initial={}}
        \begin{scope}[rotate={360/#3 * \r}, #1, polygram layer \r]
            \draw (90:{#2}) node[polygram dot] {}   
                \foreach \x in {1,...,\polygramnodesperlayer} {
                    -- ({360/#3 * (\x - 1) * #4 + 90}:{#2}) node[polygram dot] {}
                } -- cycle;
        \end{scope}
    }
}

\tikz \polygram[blue]{1}{5}{2};

\tikz \polygram[blue, polygram layer 1/.style={red}]{1}{12}{4};

\end{document}

在此处输入图片描述

答案2

这定义了一个键(其中Schlaefli star = p/q是整数不是共享任何因素)。这对应于广义正多边形在您链接的维基百科页面上。

此密钥也由以下部分内部使用Schlaefli comp = n/m正则复合多边形。 再次,n必须是整数。
选择n以便他们满足条件将导致 GCD 为 1,并且会绘制一个“正常”星号,就像一条边一样。


两者都只适用于整数。从技术上讲,并非所有 s\pgfinteval都是必需的(它们通过 eTeX 的原语执行整数运算),但它们一起.expanded降低了多次评估同一表达式的需要。

如果需要更改半径,请使用scale或更改xy价值坐标坐标系。变换rotate可用于旋转整个多边形。


我选择不定义一个\draw自行发出的命令,而是将其实现为一个键。这意味着,控制权掌握在你手中,由你实际控制\draw。你也可以使用\fill或其他选项,而无需额外的界面。

复合多边形是通过 实现的,edge这意味着它们可以各自具有不同的颜色或其他选项。(您可以绘制一个,填充另一个,然后为第三个设置图案……)这通过Schlaefli edge带有两个参数的键来控制,即当前边和边的总数。不过,它们从 0 到−1 而不是 1

类似的,Schlaefli dot键获取转发的角点的编号(从0开始数),可以用作#1

因此

\tikz[
  scale=2,
  ultra thick,
  Schlaefli edge/.style 2 args={
    draw=c#1,
    Schlaefli dot/.append style={thick, minimum size=2mm, fill=c#1, draw=c##1}},
  color let/.code args={#1=#2}{\colorlet{c#1}{#2}},
  color let/.list={
    0=red, 1=orange, 2=yellow, 3=green, 4=blue, 5=violet, 6=magenta}
] \path[Schlaefli comp=28/7];

你可以制作这个,呃,美丽的图片:

在此处输入图片描述


我正在使用我的库的full arc键和R后缀运算符ext.misctikz-ext包裹因为它允许我不必自己计算角度步长。只需给出选项full arc = 5就意味着1R等于 72°,2R等于 144° 等等。这当然不是必要的,事实上,Schlaefli comp我使用显式版本来旋转每个多边形。

代码

\documentclass[tikz]{standalone}
\usetikzlibrary{ext.misc}
\tikzset{
  Schlaefli dot/.style={
    shape=circle, inner sep=+0pt, fill, minimum size=+2.5pt, node contents=},
  Schlaefli star/.style args={#1/#2}{
    full arc={#1},
    insert path={
      (0R:1 and 1) node[Schlaefli dot=0]
        foreach \CORNER in {1,...,\pgfinteval{#1-1}}{
        -- ({\CORNER*(#2)*1R}:1 and 1) node[Schlaefli dot/.expanded=\CORNER]}
        -- cycle}},
  Schlaefli comp/.style args={#1/#2}{
    /utils/exec=\pgfmathgcd{#1}{#2}\let\tikzSchlaefliGCD\pgfmathresult,
    insert path={
     foreach[expand list] \POLY in {0, ..., \pgfinteval{\tikzSchlaefliGCD-1}}{
       (0,0) edge[
         Schlaefli edge/.try/.expanded={\POLY}{\pgfinteval{\tikzSchlaefliGCD-1}},
         to path/.expanded={[rotate=\pgfinteval{360/(#1)*\POLY},
           Schlaefli star=\pgfinteval{(#1)/\tikzSchlaefliGCD}/%
                          \pgfinteval{(#2)/\tikzSchlaefliGCD}]}]()}}}}
\begin{document}
\tikz[
  thick, line join=round,
  Schlaefli edge/.style 2 args={
    color/.pgfmath wrap={red!##1!orange}{#1/#2*100}},
  row sep=1mm, column sep=1mm]
\matrix{
  \draw[Schlaefli star= 5/2];
& \draw[Schlaefli star= 7/2];
& \draw[Schlaefli star= 7/3];
& \draw[Schlaefli star= 8/3]; \\
% https://en.wikipedia.org/wiki/Heptagram#/media/File:Heptagrams.svg
  \tikzset{Schlaefli dot/.append style=coordinate, rotate=90}
  \draw[red,   Schlaefli star=7/1];
  \draw[blue,  Schlaefli star=7/2];
  \draw[green, Schlaefli star=7/3];
& \draw[Schlaefli star= 9/2];
& \draw[Schlaefli star= 9/4];
& \draw[Schlaefli star=10/3]; \\
  \path[Schlaefli comp= 6/2];
& \path[Schlaefli comp= 9/3];
& \path[Schlaefli comp=12/4];
& \path[Schlaefli comp= 8/2]; \\
  \path[Schlaefli comp=12/3];
& \path[Schlaefli comp=10/2];
& \path[Schlaefli comp=10/4];
& \path[
    c0/.style=red, c1/.style=green, c2/.style=orange,
    c3/.style=blue, c4/.style=yellow!50!black,
    Schlaefli edge/.append style=c##1,
    Schlaefli dot/.append style=black,
    Schlaefli comp=15/6];
\\};

\tikz[
  scale=2,
  ultra thick,
  Schlaefli edge/.style 2 args={
    draw=c#1,
    Schlaefli dot/.append style={thick, minimum size=2mm, fill=c#1, draw=c##1},
  },
  color let/.code args={#1=#2}{\colorlet{c#1}{#2}},
  color let/.list={
    0=red, 1=orange, 2=yellow, 3=green, 4=blue, 5=violet, 6=magenta}
] \path[Schlaefli comp=28/7];

\begin{tikzpicture}[Schlaefli dot/.append style=coordinate, rotate=90]
  \fill[red,   Schlaefli star=7/1];
  \fill[blue,  Schlaefli star=7/2];
  \fill[green, Schlaefli star=7/3];
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

答案3

这将创建一个\nsides带有边的多边组合。

\documentclass[tikz,border=5]{standalone}

\def\nsides{5}

\begin{document}
    \begin{tikzpicture}[declare function={r=2;c=360/\nsides;}]
        \foreach \i in {1,...,\nsides}{
            \draw[blue](\i*c:r)--(\i*c+2*c:r);
            \fill[red](\i*c:r)circle(.03);
        }
    \end{tikzpicture}
\end{document}

相关内容