使用笛卡尔坐标在 LaTex 中绘制六角形格子

使用笛卡尔坐标在 LaTex 中绘制六角形格子

我想使用 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}

在此处输入图片描述

相关内容