答案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}