-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathpoisson.psvg
80 lines (70 loc) · 2.6 KB
/
poisson.psvg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<!-- poisson.psvg -->
<!-- poisson disk sampling -->
<!-- based on paper https://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf -->
<!-- and this impl. https://editor.p5js.org/codingtrain/sketches/4N78DFCXN -->
<psvg width="300" height="300" background="black">
<def-dist2 x0="" y0="" x1="" y1="">
<var dx="{x0-x1}"/>
<var dy="{y0-y1}"/>
<return value="{dx*dx+dy*dy}"/>
</def-dist2>
<def-poissondisk r="4" k="30">
<var active=""/>
<var w="{r/SQRT(2)}"/>
<var r2="{r*r}"/>
<var cols="{FLOOR(WIDTH/w)}"/>
<var rows="{FLOOR(HEIGHT/w)}"/>
<var grid="{FILL(-1,cols*rows)}"/>
<var samples="{WIDTH/2} {HEIGHT/2}"/>
<for i="0" true="{i<COUNT(samples)}" step="2">
<asgn active="{CAT(active,NTH(samples,i),NTH(samples,i+1))}"/>
<var col="{FLOOR(NTH(samples,i)/w)}"/>
<var row="{FLOOR(NTH(samples,i+1)/w)}"/>
<asgn grid="{UPDATE(grid,row*cols+col,i/2)}"/>
</for>
<while true="{COUNT(active)}">
<var ridx="{FLOOR(RANDOM()*COUNT(active)/2)}"/>
<var pos="{TAKE(DROP(active,ridx*2),2)}"/>
<var found="0"/>
<for n="0" true="{n<k}" step="1">
<var sr="{RANDOM()*r+r}"/>
<var sa="{RANDOM()*PI*2}"/>
<var sx="{NTH(pos,0)+sr*COS(sa)}"/>
<var sy="{NTH(pos,1)+sr*SIN(sa)}"/>
<var col="{FLOOR(sx/w)}"/>
<var row="{FLOOR(sy/w)}"/>
<if true="{col>0 && row>0 &&
col<cols-1 && row<rows-1}">
<var ok="1"/>
<for i="-1" true="{i<=1}" step="1">
<for j="-1" true="{j<=1}" step="1">
<var idx="{(row+i)*cols+col+j}"/>
<var nbr="{NTH(grid,idx)}"/>
<if true="nbr!=-1">
<var d="{dist2(sx,sy,NTH(samples,nbr*2),NTH(samples,nbr*2+1))}"/>
<if true="{d<r2}">
<asgn ok="0"/>
</if>
</if>
</for>
</for>
<if true="{ok}">
<asgn found="1"/>
<asgn grid="{UPDATE(grid,row*cols+col,COUNT(samples)/2)}"/>
<var sample="{sx} {sy}"/>
<asgn active="{CAT(active,sample)}"/>
<asgn samples="{CAT(samples,sample)}"/>
</if>
</if>
</for>
<if false="{found}">
<asgn active="{CAT(TAKE(active,ridx*2),DROP(active,ridx*2+2))}"/>
</if>
</while>
<for i="0" true="{i<COUNT(samples)}" step="2">
<fill color="hsl({i/5},80%,80%)"/>
<circle cx="{NTH(samples,i)}" cy="{NTH(samples,i+1)}" r="1.2"/>
</for>
</def-poissondisk>
<poissondisk/>
</psvg>