我一直在尝试创建一个命令来概括这一点,但我不知道我做错了什么。也许它比我想象的要复杂。我该怎么做?请包括步骤描述,因为我对 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}
而且因为我最近非常喜欢pic
s,所以使用 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
或更改x
和y
价值的坐标坐标系。变换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.misc
tikz-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}