如何使用 Tikz 绘制(和描绘)一系列点的 Voronoi 区域?

如何使用 Tikz 绘制(和描绘)一系列点的 Voronoi 区域?

如何使用 Tikz 绘制(和绘制)平面中一系列点的 Voronoi 区域?如果这些点在 3D 空间中怎么办?

答案1

这是使用 TikZ 的一个解决方案。

\documentclass[preview, border=7mm]{standalone}
\usepackage{xinttools} % for the \xintFor***
\usepackage{tikz}
\usetikzlibrary{calc}


\def\biglen{20cm} % playing role of infinity (should be < .25\maxdimen)
% define the "half plane" to be clipped (#1 = half the distance between cells)
\tikzset{
  half plane/.style={ to path={
       ($(\tikztostart)!.5!(\tikztotarget)!#1!(\tikztotarget)!\biglen!90:(\tikztotarget)$)
    -- ($(\tikztostart)!.5!(\tikztotarget)!#1!(\tikztotarget)!\biglen!-90:(\tikztotarget)$)
    -- ([turn]0,2*\biglen) -- ([turn]0,2*\biglen) -- cycle}},
  half plane/.default={1pt}
}

\def\n{23} % number of random points
\def\maxxy{4} % random points are in [-\maxxy,\maxxy]x[-\maxxy,\maxxy]

\begin{document}

  \begin{tikzpicture}
    % generate random points
    \pgfmathsetseed{1908} % init random with the year Voronoi published his paper ;)
    \def\pts{}
    \xintFor* #1 in {\xintSeq {1}{\n}} \do{
      \pgfmathsetmacro{\ptx}{.9*\maxxy*rand} % random x in [-.9\maxxy,.9\maxxy]
      \pgfmathsetmacro{\pty}{.9*\maxxy*rand} % random y in [-.9\maxxy,.9\maxxy]
      \edef\pts{\pts, (\ptx,\pty)} % stock the random point
    }

    % draw the points and their cells
    \xintForpair #1#2 in \pts \do{
      \edef\pta{#1,#2}
      \begin{scope}
        \xintForpair \#3#4 in \pts \do{
          \edef\ptb{#3,#4}
          \ifx\pta\ptb\relax % check if (#1,#2) == (#3,#4) ?
            \tikzstyle{myclip}=[];
          \else
            \tikzstyle{myclip}=[clip];
          \fi;
          \path[myclip] (#3,#4) to[half plane] (#1,#2);
        }
        \clip (-\maxxy,-\maxxy) rectangle (\maxxy,\maxxy); % last clip
        \pgfmathsetmacro{\randhue}{rnd}
        \definecolor{randcolor}{hsb}{\randhue,.5,1}
        \fill[randcolor] (#1,#2) circle (4*\biglen); % fill the cell with random color
        \fill[draw=red,very thick] (#1,#2) circle (1.4pt); % and draw the point
      \end{scope}
    }
    \pgfresetboundingbox
    \draw (-\maxxy,-\maxxy) rectangle (\maxxy,\maxxy);
  \end{tikzpicture}

\end{document}

在此处输入图片描述

关于代码的一些评论:

  • 给定两点 A 和 B,靠近 A 的点构成一个半平面,由垂直平分线,且含有 A。
  • 因此,为了构建 A 的 Voronoi 单元,我们可以在 B 经过所有其他点(不同于 A)时取所有半平面的交点。
  • 在代码中,通过剪切充当“半平面”角色的大矩形来实现此交点。
  • 我无法使用,\foreach因为在这样的循环内进行剪辑在循环外不可用(\foreach创建一个组)。所以我通过使用来克服这个问题\xintFor

相关内容