我想使用 Tikz/PSTricks 或 LaTex 中的类似包重现六角形晶格,如下图所示。
已经有多种答案了这里。但是,它们都使用 for 循环,而我想以更可控的方式创建六边形的排列,即逐个使用笛卡尔 x,y 坐标。
是否可以通过这种方式创建至少前两行格子?
我正在为下面的单个六边形添加代码(这需要修改,因为格点放置不正确)。是否可以重复此结构以确保最左上角的坐标为 (-1,0) 且边为单位长度?
\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows,decorations.markings}
\begin{document}
%% Create a hexagon:
\begin{tikzpicture}
% For a hexagons the coordinates for the vertices in a sequence:
% (-1,0), (-1/2,sqrt{3}/2), (1/2,sqrt{3}/2), (1,0), (1/2,-sqrt{3}/2), (-1/2,-sqrt{3}/2)
% sqrt{3}/2 = 0.866 (approx)
\draw [*-, color=red] (-1,0) -- (-0.5,0.866);
\draw [*-, color=red] (-0.5,0.866) -- (0.5,0.866);
\draw [*-, color=red] (0.5,0.866) -- (1,0);
\draw [*-, color=red] (1,0) -- (0.5,-0.866);
\draw [*-, color=red] (0.5,-0.866) -- (-0.5,-0.866);
\draw [*-, color=red] (-0.5,-0.866) -- (-1,0);
\end{tikzpicture}
\end{document}
根据你的建议,我对此做了一些修改。我想显示一个完整六边形的坐标:
\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows,decorations.markings}
\begin{document}
\begin{tikzpicture}
\draw [color=red,mark=*] plot[samples at={-180,-120,...,180},variable=\x]
(\x:1);
\node[color=black, left] at (-1,0) {\small (-1,0)};
\node[color=black, left] at (-0.5,0.866) {\small (-0.5,0.866)};
\node[color=black, left] at (-0.5,-0.866) {\small (-0.5,-0.866)};
\node[color=black, right] at (1,0) {\small (1,0)};
\node[color=black, right] at (0.5,0.866) {\small (0.5,0.866)};
\node[color=black, right] at (0.5,-0.866) {\small (0.5,-0.866)};
\end{tikzpicture}
\end{document}
输出:
构建完整个格子后我可以这样做吗?
答案1
让我提一下,你的代码可以简化为
\documentclass[tikz,border=3mm]{standalone}
\begin{document}
\begin{tikzpicture}
\draw [color=red,mark=*] plot[samples at={-180,-120,...,180},variable=\x]
(\x:1);
\end{tikzpicture}
\end{document}
正如您所见,这解决了圆圈未对齐的问题(这是因为您是通过箭头添加圆圈的;您可以通过缩短路径来解决问题,但我觉得这更简单)。
问题是这包含硬编码距离等。幸运的是,该patterns.meta
库最近找到了手册,这使我们能够避免这个问题。正如@cfr指出的那样,您只需要其中一个,因为它们通过旋转相关,并且使用创建的模式patterns.meta
是可旋转,并且可以调整其他参数,例如线宽和大小(当然,您还可以拨打颜色)。
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{patterns.meta}
\begin{document}
\tikzdeclarepattern{name=hexa,
parameters={
\pgfkeysvalueof{/pgf/pattern keys/size},
\pgfkeysvalueof{/pgf/pattern keys/angle},
\pgfkeysvalueof{/pgf/pattern keys/line width},
},
bounding box={(-.1pt,-.1pt) and
(1.5*\pgfkeysvalueof{/pgf/pattern keys/size}+.1pt,
{sin(60)*\pgfkeysvalueof{/pgf/pattern keys/size}+.1pt})},
tile size={(1.5*\pgfkeysvalueof{/pgf/pattern keys/size},
{sin(60)*\pgfkeysvalueof{/pgf/pattern keys/size}})},
tile transformation={rotate=\pgfkeysvalueof{/pgf/pattern keys/angle}},
defaults={
size/.initial=5pt,
angle/.initial=0,
line width/.initial=.4pt,
}, code={
\draw[line width=\pgfkeysvalueof{/pgf/pattern keys/line width}]
(0,{\pgfkeysvalueof{/pgf/pattern keys/size}*sin(60)/2})
-- ({\pgfkeysvalueof{/pgf/pattern keys/size}*1/4},0)
-- ({\pgfkeysvalueof{/pgf/pattern keys/size}*3/4},0)
-- (\pgfkeysvalueof{/pgf/pattern keys/size},{\pgfkeysvalueof{/pgf/pattern keys/size}*sin(60)/2})
(0.75*\pgfkeysvalueof{/pgf/pattern keys/size},{\pgfkeysvalueof{/pgf/pattern keys/size}*sin(60)})
-- (\pgfkeysvalueof{/pgf/pattern keys/size},{\pgfkeysvalueof{/pgf/pattern keys/size}*sin(60)/2})
-- (1.5*\pgfkeysvalueof{/pgf/pattern keys/size},{\pgfkeysvalueof{/pgf/pattern keys/size}*sin(60)/2})
-- (1.75*\pgfkeysvalueof{/pgf/pattern keys/size},{\pgfkeysvalueof{/pgf/pattern keys/size}*sin(60)})
;
} }
\begin{tikzpicture}
\draw[pattern={hexa[size=10pt,line width=.8pt,angle=90]},
pattern color=blue] (0,0) rectangle ++(2,2);
\draw[pattern={hexa[size=10pt,line width=.8pt,angle=0]},
pattern color=red] (3,0) rectangle ++(2,2);
\end{tikzpicture}
\end{document}
或者用圆圈表示:
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{patterns.meta}
\begin{document}
\tikzdeclarepattern{name=hexa with circles,
parameters={
\pgfkeysvalueof{/pgf/pattern keys/size},
\pgfkeysvalueof{/pgf/pattern keys/angle},
\pgfkeysvalueof{/pgf/pattern keys/line width},
\pgfkeysvalueof{/pgf/pattern keys/radius},
},
bounding box={(-.1pt,-.1pt) and
(1.5*\pgfkeysvalueof{/pgf/pattern keys/size}+.1pt,
{sin(60)*\pgfkeysvalueof{/pgf/pattern keys/size}+.1pt})},
tile size={(1.5*\pgfkeysvalueof{/pgf/pattern keys/size},
{sin(60)*\pgfkeysvalueof{/pgf/pattern keys/size}})},
tile transformation={rotate=\pgfkeysvalueof{/pgf/pattern keys/angle}},
defaults={
size/.initial=5pt,
angle/.initial=0,
line width/.initial=.4pt,
radius/.initial=1.2pt,
}, code={
\draw[line width=\pgfkeysvalueof{/pgf/pattern keys/line width}]
(0,{\pgfkeysvalueof{/pgf/pattern keys/size}*sin(60)/2})
-- ({\pgfkeysvalueof{/pgf/pattern keys/size}*1/4},0)
-- ({\pgfkeysvalueof{/pgf/pattern keys/size}*3/4},0)
-- (\pgfkeysvalueof{/pgf/pattern keys/size},{\pgfkeysvalueof{/pgf/pattern keys/size}*sin(60)/2})
(0.75*\pgfkeysvalueof{/pgf/pattern keys/size},{\pgfkeysvalueof{/pgf/pattern keys/size}*sin(60)})
-- (\pgfkeysvalueof{/pgf/pattern keys/size},{\pgfkeysvalueof{/pgf/pattern keys/size}*sin(60)/2})
-- (1.5*\pgfkeysvalueof{/pgf/pattern keys/size},{\pgfkeysvalueof{/pgf/pattern keys/size}*sin(60)/2})
-- (1.75*\pgfkeysvalueof{/pgf/pattern keys/size},{\pgfkeysvalueof{/pgf/pattern keys/size}*sin(60)});
\fill
(0,{\pgfkeysvalueof{/pgf/pattern keys/size}*sin(60)/2}) circle[radius=\pgfkeysvalueof{/pgf/pattern keys/radius}]
({\pgfkeysvalueof{/pgf/pattern keys/size}*1/4},0) circle[radius=\pgfkeysvalueof{/pgf/pattern keys/radius}]
({\pgfkeysvalueof{/pgf/pattern keys/size}*3/4},0) circle[radius=\pgfkeysvalueof{/pgf/pattern keys/radius}]
(\pgfkeysvalueof{/pgf/pattern keys/size},{\pgfkeysvalueof{/pgf/pattern keys/size}*sin(60)/2}) circle[radius=\pgfkeysvalueof{/pgf/pattern keys/radius}];
} }
\begin{tikzpicture}
\draw[pattern={hexa with circles[size=10pt,line width=.8pt,angle=90]},
pattern color=blue] (0,0) rectangle ++(2,2);
\draw[pattern={hexa with circles[size=10pt,line width=.8pt,angle=0]},
pattern color=red] (3,0) rectangle ++(2,2);
\end{tikzpicture}
\end{document}
附录: 为了让@BlackMild 高兴一点,这里有一个简短的版本。当然,也可以把它改成很多通过使用距离的硬编码值等等可以缩短时间,但恕我直言,这确实违背了目的。
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{patterns.meta}
\begin{document}
\def\pk#1{\pgfkeysvalueof{/pgf/pattern keys/#1}}
\tikzdeclarepattern{name=hexa with circles,
parameters={
\pk{size},
\pk{angle},
\pk{line width},
\pk{radius},
},
bounding box={(-.1pt,-.1pt) and
(1.5*\pk{size}+.1pt,
{sin(60)*\pk{size}+.1pt})},
tile size={(1.5*\pk{size},
{sin(60)*\pk{size}})},
tile transformation={rotate=\pk{angle}},
defaults={
size/.initial=5pt,
angle/.initial=0,
line width/.initial=.4pt,
radius/.initial=1.2pt,
}, code={
\draw[line width=\pk{line width}]
(0,{\pk{size}*sin(60)/2}) -- ({\pk{size}*1/4},0) -- ({\pk{size}*3/4},0) -- (\pk{size},{\pk{size}*sin(60)/2})
(0.75*\pk{size},{\pk{size}*sin(60)})-- (\pk{size},{\pk{size}*sin(60)/2}) -- (1.5*\pk{size},{\pk{size}*sin(60)/2})-- (1.75*\pk{size},{\pk{size}*sin(60)});
\fill (0,{\pk{size}*sin(60)/2}) circle[radius=\pk{radius}] ({\pk{size}*1/4},0) circle[radius=\pk{radius}]
({\pk{size}*3/4},0) circle[radius=\pk{radius}] (\pk{size},{\pk{size}*sin(60)/2}) circle[radius=\pk{radius}];
} }
\begin{tikzpicture}
\draw[pattern={hexa with circles[size=10pt,line width=.8pt,angle=90]},
pattern color=blue] (0,0) rectangle ++(2,2);
\draw[pattern={hexa with circles[size=10pt,line width=.8pt,angle=0]},
pattern color=red] (3,0) rectangle ++(2,2);
\end{tikzpicture}
\end{document}
附录 2:尝试解答您的(更新后的)问题。除了旋转图案,您还可以对它们进行其他变换,尤其是移位。
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{patterns.meta}
\begin{document}
\def\pk#1{\pgfkeysvalueof{/pgf/pattern keys/#1}}
\tikzdeclarepattern{name=hexa with circles,
parameters={
\pk{size},
\pk{angle},
\pk{line width},
\pk{radius},
\pk{xshift},
\pk{yshift},
},
bounding box={(-.1pt,-.1pt) and
(1.5*\pk{size}+.1pt,
{sin(60)*\pk{size}+.1pt})},
tile size={(1.5*\pk{size},
{sin(60)*\pk{size}})},
tile transformation={xshift=\pk{xshift},yshift=\pk{yshift},rotate=\pk{angle}},
defaults={
size/.initial=5pt,
angle/.initial=0,
line width/.initial=.4pt,
radius/.initial=1.2pt,
xshift/.initial=0pt,
yshift/.initial=0pt,
}, code={
\draw[line width=\pk{line width}]
(0,{\pk{size}*sin(60)/2}) -- ({\pk{size}*1/4},0) -- ({\pk{size}*3/4},0) -- (\pk{size},{\pk{size}*sin(60)/2})
(0.75*\pk{size},{\pk{size}*sin(60)})-- (\pk{size},{\pk{size}*sin(60)/2}) -- (1.5*\pk{size},{\pk{size}*sin(60)/2})-- (1.75*\pk{size},{\pk{size}*sin(60)});
\fill (0,{\pk{size}*sin(60)/2}) circle[radius=\pk{radius}] ({\pk{size}*1/4},0) circle[radius=\pk{radius}]
({\pk{size}*3/4},0) circle[radius=\pk{radius}] (\pk{size},{\pk{size}*sin(60)/2}) circle[radius=\pk{radius}];
} }
\begin{tikzpicture}
\draw[pattern={hexa with circles[size=2cm,line width=.8pt,radius=1.4pt,
xshift={-0.42*sin(60)*0.5cm},
yshift={-1.33*cos(60)*0.5cm}]},
pattern color=red] (-8,-8) rectangle ++(16,16);
\draw [color=red,mark=*] plot[samples at={-180,-120,...,180},variable=\x]
(\x:1);
\node[color=black, left] at (-1,0) {\small (-1,0)};
\node[color=black, left] at (-0.5,0.866) {\small (-0.5,0.866)};
\node[color=black, left] at (-0.5,-0.866) {\small (-0.5,-0.866)};
\node[color=black, right] at (1,0) {\small (1,0)};
\node[color=black, right] at (0.5,0.866) {\small (0.5,0.866)};
\node[color=black, right] at (0.5,-0.866) {\small (0.5,-0.866)};
\end{tikzpicture}
\end{document}
答案2
如果只需要六边形,则使用(xelatex
或)。可以通过另一个循环latex->dvips->ps2pdf
简化\multido
\documentclass{article}
\usepackage{pst-poly,multido}
\begin{document}
\begin{pspicture}[showgrid](-1.1,0.1)(5,-2)
\multido{\rA=-0.5+1.5}{4}{\rput(\rA,-0.5){\PstHexagon[unit=0.5]}}
\multido{\rA=0.25+1.5}{4}{\rput(\rA,-0.933){\PstHexagon[unit=0.5]}}
\multido{\rA=-0.5+1.5}{4}{\rput(\rA,-1.366){\PstHexagon[unit=0.5]}}
\multido{\rA=0.25+1.5}{4}{\rput(\rA,-1.799){\PstHexagon[unit=0.5]}}
\end{pspicture}
\bigskip
\begin{pspicture}(-1.1,0.1)(5,-2)
\psset{linecolor=red,linewidth=1.5pt}
\providecommand{\PstPolygonNode}{\psdots[dotscale=1.2](1;\INode)}
\multido{\rA=-0.5+1.5}{4}{\rput(\rA,-0.5){\PstHexagon[unit=0.5]}}
\multido{\rA=0.25+1.5}{4}{\rput(\rA,-0.933){\PstHexagon[unit=0.5]}}
\multido{\rA=-0.5+1.5}{4}{\rput(\rA,-1.366){\PstHexagon[unit=0.5]}}
\multido{\rA=0.25+1.5}{4}{\rput(\rA,-1.799){\PstHexagon[unit=0.5]}}
\end{pspicture}
\bigskip
\begin{pspicture}(-1.1,0.1)(5,-2)
\psset{linecolor=blue,linewidth=1.5pt,PolyRotation=30}
\providecommand{\PstPolygonNode}{\psdots[dotscale=1.2](1;\INode)}
\multido{\rA=-0.5+0.866}{6}{\rput(\rA,-0.5){\PstHexagon[unit=0.5]}}
\multido{\rA=-0.067+0.866}{6}{\rput(\rA,-1.25){\PstHexagon[unit=0.5]}}
\multido{\rA=-0.5+0.866}{6}{\rput(\rA,-2){\PstHexagon[unit=0.5]}}
\multido{\rA=-0.067+0.866}{6}{\rput(\rA,-2.75){\PstHexagon[unit=0.5]}}
\end{pspicture}
\end{document}
如果您需要它作为背景填充,请将其用作(运行latex->dvips->ps2pdf
)
\documentclass{article}
\usepackage[tiling]{pst-fill}
\newcommand\Tiling[2][]{%
\begin{pspicture}#2
\psframe[fillstyle=boxfill,#1]#2
\end{pspicture}}
\newcommand\Hexagon[1][showpoints,dotscale=2]{% sin(60)=0.866
\begin{pspicture}(0.866,0.75)
\pspolygon[dimen=middle,#1](0.5;30)(0.5;90)(0.5;150)(0.5;210)(0.5;270)(0.5;330)
\end{pspicture}}
\begin{document}
\psboxfill{\Hexagon}
\Tiling[fillcyclex=2,fillloopaddy=1]{(5,5)}
\psboxfill{\Hexagon[]}
\Tiling[fillcyclex=2,fillloopaddy=1]{(5,5)}
\psboxfill{\Hexagon}
\Tiling[fillcyclex=2,fillloopaddy=1,fillangle=30]{(5,5)}
\psboxfill{\Hexagon[]}
\Tiling[fillcyclex=2,fillloopaddy=1,fillangle=30]{(5,5)}
\end{document}