如何向 tikz 图表元素添加点画?

如何向 tikz 图表元素添加点画?

好吧,我想大家都知道如何在 Tikz 中绘制球体

\tikz{
\fill [black] (-1,-1) rectangle (1,1);
\shade [ball color=white] (0,0) circle [radius=1cm];
}

但是我怎样才能添加这种可以在彭罗斯的绘画中找到的效果呢?(周围的那些点)

在此处输入图片描述

一般来说,如何在 Tikz 中为任何形状创建这种效果?(这里还有一些其他图片供您欣赏)

在此处输入图片描述

在此处输入图片描述

在此处输入图片描述

在此处输入图片描述

答案1

这需要年龄。还需要注意路径的方向,通过选择性地将点画应用于路径的某些部分可以实现最佳效果。所以,基本上,这真的很麻烦。但是(与许多事物一样)从远处看起来相当不错。

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{decorations}
\pgfkeys{/pgf/decoration/.cd,
  stipple density/.store in=\pgfstippledensity,
  stipple density=.1,
  stipple scaling function/.store in=\pgfstipplescalingfunction,
  stipple scaling function=sin(\pgfstipplex*180)*0.875+0.125,
  stipple radius/.store in=\pgfstippleradius,
  stipple radius=0.25pt
}
\pgfdeclaredecoration{stipple}{draw}{
\state{draw}[width=\pgfdecorationsegmentlength]{%
  \pgfmathparse{\pgfdecoratedcompleteddistance/\pgfdecoratedpathlength}%
  \let\pgfstipplex=\pgfmathresult%
  \pgfmathparse{int(\pgfstippledensity*100)}%
  \let\pgfstipplen=\pgfmathresult%
  \pgfmathloop%
  \ifnum\pgfmathcounter<\pgfmathresult\relax%
    \pgfpathcircle{%
      \pgfpoint{(rnd)*\pgfdecorationsegmentlength}%
        {(\pgfstipplescalingfunction)*(rnd^4)*\pgfdecorationsegmentamplitude+\pgfstippleradius}}% 
    {\pgfstippleradius}%
  \repeatpgfmathloop%
}
}

\tikzset{stipple/.style={
  decoration={stipple, segment length=2pt, #1},
  decorate,
  fill
}}
\begin{document}
\begin{tikzpicture}
\draw [postaction={stipple={amplitude=0.125cm}}] 
  (0,0) [rotate=45]  circle [radius=1];
\path [postaction={stipple={amplitude=0.25cm, stipple density=.35}},
  postaction={stipple={amplitude=0.35cm, stipple density=.15}}]
  (135:1) arc (135:315:1);
\end{tikzpicture}

\end{document}

在此处输入图片描述

这甚至需要更长

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{decorations}
\pgfkeys{/pgf/decoration/.cd,
  stipple density/.store in=\pgfstippledensity,
  stipple density=(sin(\pgfstipplex*180)*0.25+0.1),
  stipple amplitude/.store in=\pgfstippleamplitude,
  stipple amplitude=(rnd^3)*\pgfstippley*(sin(\pgfstipplex*180)^2+0.05),
  stipple radius/.store in=\pgfstippleradius,
  stipple radius=0.25pt
}
\pgfdeclaredecoration{stipple}{draw}{
\state{draw}[width=\pgfdecorationsegmentlength]{%
  \pgfmathparse{\pgfdecoratedcompleteddistance/\pgfdecoratedpathlength}%
  \let\pgfstipplex=\pgfmathresult%
  \let\pgfstippley=\pgfdecorationsegmentamplitude%
  \pgfmathparse{int(abs((\pgfstippledensity)*100))}%
  \let\pgfstipplen=\pgfmathresult%
  \pgfmathloop%
  \ifnum\pgfmathcounter<\pgfmathresult\relax%
    \pgfpathcircle{%
      \pgfpoint{(rnd-0.5)*\pgfdecorationsegmentlength}%
        {(\pgfstippleamplitude)+\pgfstippleradius}}% 
    {\pgfstippleradius}%
  \repeatpgfmathloop%
}
}

\tikzset{stipple/.style={
  decoration={stipple, segment length=2pt, #1},
  decorate,
  fill
}}
\begin{document}
\begin{tikzpicture}[x=2em,y=2em]
\draw [postaction={stipple={amplitude=0.5cm}},
      postaction={stipple={amplitude=0.25cm}}] 
  (2,1) ..controls ++(135:1) and ++(90:1) .. 
  (0,0) .. controls ++(270:1) and ++(180:1.5) .. 
  (2,-2) .. controls ++(0:1.5) and ++(270:2) .. 
  (5,1) .. controls ++(90:2) and ++(75:1) .. 
  (2,1) .. controls ++(255:1/4) and ++(0:1/2) .. (3/2,0);
\draw [postaction={stipple={amplitude=0.125cm, stipple density=0.05}},
  postaction={stipple={amplitude=0.5cm, reverse path}},
  postaction={stipple={amplitude=0.25cm, reverse path}}] 
  (3,0) .. controls ++(135:1) and ++(90:1) .. (4,1);
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

看来我得提高一下水平了。Mark Wibrow 给出了一个很好的答案,但这个答案有几个优点,包括对点进行灰度处理,使内部的点更浅,每次运行时都能获得完全可预测和可复制的结果,以及控制所有参数。(例如,您可以通过更改\thisrowno{1}两个位置的指数来更改点画厚度的变化量。)它在 LuaLaTeX 以外的引擎中运行也非常快。

\PassOptionsToPackage{svgnames}{xcolor}
\documentclass{standalone}
\usepackage{pgfplots}

\pgfplotsset{width=\textwidth,compat=1.12}

\begin{document}

\begin{tikzpicture}
\begin{axis}[trig format plots=rad, width=5cm,axis equal,
             xmin = -1, xmax = 1,
             axis x line = none, axis y line = none]
  \addplot [variable=\t,domain=0:2*pi,samples=30,smooth]({cos t},{sin t});
%% θ(u) = 2πku, r(t) = t^c
  \addplot+ [scatter,scatter src=0.6*(1-\thisrowno{0}^0.125)+0.2,
             only marks,mark=*,mark size=0.001cm,colormap/blackwhite]
            table[header=false,
                  x expr=\thisrowno{0}^0.125*cos(7*pi/3+sign(\thisrowno{2}-0.5)*pi*\thisrowno{1}^0.5),
                  y expr=\thisrowno{0}^0.125*sin(7*pi/3+sign(\thisrowno{2}-0.5)*pi*\thisrowno{1}^0.5),
                 ]
                 {randtuple.dat}; % A file of three columns of random numbers from [0,1).
\end{axis}
\end{tikzpicture}

\end{document}

粗细不一的点画粗细不一的点画

为了完整性,下面是生成随机数据的程序,尽管可以pgfmath使用来生成它rand

#include <cmath>
#include <ctime>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <random>

using std::cout;

int main(void)
{
  static const ssize_t ncols = 1000;
  static const unsigned sigfigs = 17;
  static const unsigned width = 22;
  static const double interval = std::exp2(-64.0L);

  std::mt19937_64 rng( static_cast<std::mt19937_64::result_type>(
                         time(NULL)*CLOCKS_PER_SEC+clock() ) );

  cout.precision(sigfigs);

  for ( ssize_t i = 0; i < ncols; ++i ) {
    const double x = rng() * interval;
    const double y = rng() * interval;
    const double z = rng() * interval;

    cout << std::setw(width) << x << " "
         << std::setw(width) << y << " "
         << std::setw(width) << z << "\n";
  }

  return EXIT_SUCCESS;
}

我们也可以取点列() ∊ [0,1]×[0,1] 从均匀随机分布中抽取,并将它们映射到 r() =^C,θ() = 2π

它看起来是这样的:

在此处输入图片描述

\PassOptionsToPackage{svgnames}{xcolor}
\documentclass{standalone}
\usepackage{pgfplots}

\pgfplotsset{width=\textwidth,compat=1.12}

\begin{document}

\begin{tikzpicture}
\begin{axis}[trig format plots=rad, width=5cm,axis equal,
             xmin = -1, xmax = 1,
             axis x line = none, axis y line = none]
  \addplot [variable=\t,domain=0:2*pi,samples=30,smooth]({cos t},{sin t});
%% θ(u) = 2πku, r(t) = t^c
  \addplot+ [scatter,scatter src=0.8*(1-\thisrowno{0}^0.125),
             only marks,mark=*,mark size=0.001cm,colormap/blackwhite]
            table[header=false,
                  x expr=\thisrowno{0}^0.125*cos(10*pi*\thisrowno{1}),
                  y expr=\thisrowno{0}^0.125*sin(10*pi*\thisrowno{1}),
                 ]
                 {randpairs.dat}; % A file of two columns of random numbers from [0,1).
\end{axis}
\end{tikzpicture}

\end{document}

旧版本

也许可以得到一条线上的点的噪声分布,将它们参数化为一个螺旋,其外部比内部盘绕得更紧密,例如为了∊[0,1],>1, 0<C<1,θ) = 2πr) =^C,并绘制它们?

\PassOptionsToPackage{svgnames}{xcolor}
\documentclass{standalone}
\usepackage{pgfplots}

\pgfplotsset{width=\textwidth,compat=1.12}

\begin{document}

\begin{tikzpicture}
\begin{axis}[trig format plots=rad, width=5cm,axis equal,
             xmin = -1, xmax = 1,
             axis x line = none, axis y line = none]
  \addplot[variable=\t,domain=0:2*pi,samples=30,smooth]({cos t},{sin t});
%% θ(t) = 2πk·√t, r(t) = t^c
%% x(t) = r(t) cos θ(t) = t^c cos 2πk√t
%% y(t) = r(t) sin θ(t) = t^c sin 2πk√t
%% Where t ∊ [0,1], k>1, 0<c<1
%%
%% To eliminate the first half-revolution, solve for 2πk√t = π.  A prime
%% number in the sample size is less likely to produce unattractive patterns.
  \addplot+[variable=\t,domain=0.01:1,samples=193,
            only marks,mark=*,mark size=0.01cm,
            mark options={draw=DimGray,fill=DimGray}]
           ({t^0.125*cos(10*pi*t^0.5)},{t^0.125*sin(10*pi*t^0.5});
\end{axis}
\end{tikzpicture}

\end{document}

在此处输入图片描述

为了简单起见,点的分布中没有噪音,但对我来说它仍然看起来相当不错。

答案3

好的,开始使用 lualatex 进行编译。

\documentclass{article}

\usepackage{tikz}
\usepackage{luacode}



\begin{document}


\begin{tikzpicture}
\draw (0,0) circle(5cm);
\begin{luacode*}
math.randomseed(os.time())
for i=1,1000 do
r=math.random()*3.145926535*2
s=math.random()+3.9
tex.print("\\draw[fill] (" .. s*math.cos(r) .. "," .. s*math.sin(r) ..") circle(0.2mm);")
end
 \end{luacode*}
\end{tikzpicture}

\end{document}

在此处输入图片描述

还有一个更复杂的例子:

\documentclass{article}

\usepackage{tikz}
\usepackage{luacode}



\begin{document}


\begin{tikzpicture}
\draw (0,0) circle(5cm);
\begin{luacode*}
math.randomseed(os.time())
for i=1,1000 do
r=math.sqrt(math.random())*3.145926535*2
s=math.pow(math.random(),0.2)+3.99
tex.print("\\draw[fill] (" .. s*math.cos(r) .. "," .. s*math.sin(r) ..") circle(0.2mm);")
end
 \end{luacode*}
\end{tikzpicture}

\end{document}

在此处输入图片描述

更好的是:

\documentclass{article}

\usepackage{tikz}
\usepackage{luacode}



\begin{document}


\begin{tikzpicture}
\draw (0,0) circle(5cm);
\begin{luacode*}
math.randomseed(os.time())
for i=1,1000 do
r=math.sqrt(math.random())*3.145926535*2
s=math.pow(math.random(),0.1)*4.99
tex.print("\\draw[fill] (" .. s*math.cos(r) .. "," .. s*math.sin(r) ..") circle(0.2mm);")
end
 \end{luacode*}
\end{tikzpicture}

\end{document}

在此处输入图片描述

最好的:

\documentclass{article}

\usepackage{tikz}
\usepackage{luacode}



\begin{document}


\begin{tikzpicture}
\draw (0,0) circle(5cm);
\begin{luacode*}
math.randomseed(os.time())
for i=1,1000 do
if math.random() > 0.5 then b=1 else b= -1 end
r=(b*math.sqrt(math.random())+1)*math.pi
s=math.pow(math.random(),0.1)*4.99
tex.print("\\draw[fill] (" .. s*math.cos(r) .. "," .. s*math.sin(r) ..") circle(0.3mm);")
end
 \end{luacode*}
\end{tikzpicture}

\end{document}

在此处输入图片描述

答案4

我猜这不是你想要的。但它看起来也像旧书里的图片。

我刚刚申请有序抖动这里的球体

理论上,对于任何功能着色,总是可以通过后记. (除非堆栈溢出。)

分辨率是硬编码的,但仍然可以更改分辨率。(但如果分辨率太高,则毫无意义。)

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

\pgfdeclarefunctionalshading{ordered dithering sphere}{\pgfpoint{0bp}{0bp}}{\pgfpoint{50bp}{50bp}}{}{
    2 copy
    %
    50 div 128 mul floor 63.5 sub 64 div exch
    50 div 128 mul floor 63.5 sub 64 div exch
    2 copy
    dup mul exch dup mul add sqrt 3 1 roll
    %
    2 copy 
    dup mul exch
    dup mul add
    1.0 sub
    0.3 dup mul
    -0.5 dup mul add
    1.0 sub
    mul abs sqrt
    exch 0.3 mul add
    exch -0.5 mul add
    dup abs add 2.0 div 
    0.6 mul 0.4 add
    %
    exch .98 ge {pop 1} if
    3 1 roll
    %
    50 div exch 50 div 1 % y x 1
    %
    3 1 roll 8 mul dup floor sub
    2 1 roll 8 mul dup floor sub
    3 2 roll
    %
    3 1 roll 2 mul dup floor dup 3 1 roll sub 3 2 roll 2 mul dup floor dup 3 1 roll sub
    4 3 roll 3 2 roll 2 copy -4 mul mul exch 3 mul add exch 2 mul add 4 mul 4 3 roll add
    %
    3 1 roll 2 mul dup floor dup 3 1 roll sub 3 2 roll 2 mul dup floor dup 3 1 roll sub
    4 3 roll 3 2 roll 2 copy -4 mul mul exch 3 mul add exch 2 mul add 16 mul 4 3 roll add
    %
    3 1 roll 2 mul dup floor dup 3 1 roll sub 3 2 roll 2 mul dup floor dup 3 1 roll sub
    4 3 roll 3 2 roll 2 copy -4 mul mul exch 3 mul add exch 2 mul add 64 mul 4 3 roll add
    %
    3 1 roll 2 mul dup floor dup 3 1 roll sub 3 2 roll 2 mul dup floor dup 3 1 roll sub
    4 3 roll 3 2 roll 2 copy -4 mul mul exch 3 mul add exch 2 mul add 256 mul 4 3 roll add
    %
    1025 div
    3 index
    le
    {1}{0}ifelse
    dup dup
}

\begin{document}
    \tikz\shade[shading=ordered dithering sphere](0,0)circle[radius=5cm];
\end{document}

相关内容